123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552 |
- <template>
- <cl-crud ref="Crud" class="orderList">
- <cl-row>
- <cl-filter-group :items="items" :data="filterParam" :reset-btn="true" />
- <cl-export-btn :columns="Table?.columns" />
- </cl-row>
- <cl-row>
- <el-checkbox v-model="showSummary" label="统计数据" size="small" />
- <el-tag v-if="showSummary" class="ml-2" effect="light">成功总金额: {{ summary.num1 }}</el-tag>
- <el-tag v-if="showSummary" class="ml-2" effect="light">成功订单手续费: {{ summary.num2 }}</el-tag>
- <el-tag v-if="showSummary && checkPerm(service.dj.order.permission.update)" class="ml-2"
- effect="light">通道手续费: {{ summary.num5.toFixed(2) }}</el-tag>
- <el-tag v-if="showSummary" class="ml-2" effect="light">成功订单数: {{ summary.num3 }}</el-tag>
- <el-tag v-if="showSummary" class="ml-2" effect="light">成功率: {{ summary.num4.toFixed(2) }}%</el-tag>
- </cl-row>
- <cl-row>
- <!-- 数据表格 -->
- <cl-table ref="Table" :contextMenu="[]">
- <template #column-detail="{ scope }">
- <div style="padding: 10px;">
- <el-descriptions border :column="4" class="desc">
- <el-descriptions-item :span="2" label="付款时间">
- {{ scope.row.date }}
- </el-descriptions-item>
- <el-descriptions-item :span="1" label="用户ID">
- {{ scope.row.userId }}
- </el-descriptions-item>
- <el-descriptions-item :span="1" label="用户IP">
- {{ scope.row.userIp }}
- </el-descriptions-item>
- <el-descriptions-item :span="4" label="通知地址">
- {{ scope.row.notifyUrl }}
- </el-descriptions-item>
- <el-descriptions-item :span="4" label="同步跳转地址">
- {{ scope.row.returnUrl }}
- </el-descriptions-item>
- <el-descriptions-item :span="4" label="支付地址">
- {{ scope.row.payUrl }}
- </el-descriptions-item>
- <el-descriptions-item :span="4" label="备注/失败描述">
- {{ scope.row.remark }}
- </el-descriptions-item>
- </el-descriptions>
- </div>
- </template>
- </cl-table>
- </cl-row>
- <cl-row>
- <cl-flex1 />
- <!-- 分页控件 -->
- <cl-pagination />
- </cl-row>
- <!-- 新增、编辑 -->
- <cl-upsert ref="Upsert" />
- <cl-form ref="Form" />
- </cl-crud>
- </template>
- <script lang="ts" name="pay-order" setup>
- import { useCrud, useTable, useUpsert, useForm } from "@cool-vue/crud";
- import { ref } from "vue";
- import { useCool } from "/@/cool";
- import dayjs from "dayjs";
- import { ElMessage } from "element-plus";
- import { checkPerm } from "/$/base";
- const Form = useForm();
- const { service } = useCool();
- const showSummary = ref(false);
- const filterParam = ref({
- createTime: [
- dayjs().format("YYYY-MM-DD ") + "00:00:00",
- dayjs().format("YYYY-MM-DD ") + "23:59:59"
- ]
- });
- function openRefund(data: any) {
- Form.value?.open({
- title: "发起退款",
- width: "800px",
- form: {
- orderNo: data.orderNo,
- reson: data.reson,
- amount: data.amount
- },
- items: [
- {
- prop: "orderNo",
- label: "订单号",
- component: {
- name: "el-input",
- props: {
- disabled: true
- }
- },
- required: true
- },
- {
- label: "金额",
- prop: "amount",
- required: true,
- component: {
- name: "el-input-number",
- props: {
- style: { width: "200px" },
- precision: 2,
- min: 0,
- disabled: true
- }
- }
- },
- {
- prop: "reson",
- label: "退款原因",
- component: { name: "el-input", props: { type: "textarea", rows: 4 } },
- }
- ],
- on: {
- async submit(data, { done, close }) {
- try {
- await service.dj.order.toRefund(data);
- ElMessage.success("订单发起退款成功,请到退款订单页面查询结果");
- close()
- } catch (e) {
- ElMessage.error(e.message);
- close()
- }
- }
- }
- });
- }
- const summary = ref({
- num1: 0,
- num2: 0,
- num3: 0,
- num4: 0,
- num5: 0
- });
- const items = ref<ClForm.Item[]>([
- {
- label: "订单号",
- prop: "orderNo",
- component: {
- name: "el-input"
- }
- },
- {
- label: "商户订单号",
- prop: "outOrderNo",
- component: {
- name: "el-input"
- }
- },
- {
- label: "交易号",
- prop: "traceNo",
- component: {
- name: "el-input"
- }
- },
- {
- label: "商户号",
- prop: "mchId",
- component: {
- name: "el-input"
- },
- hidden: !checkPerm(service.dj.order.permission.mch)
- },
- {
- label: "支付方式",
- prop: "payType",
- component: {
- name: "el-input"
- }
- },
- {
- label: "通道编码",
- prop: "code",
- component: {
- name: "el-input"
- },
- hidden: !checkPerm(service.dj.order.permission.code)
- },
- {
- label: "支付状态",
- prop: "status",
- component: {
- name: "el-select",
- props: {
- clearable: true
- },
- options: [
- {
- label: "待支付",
- value: 0
- },
- {
- label: "支付成功",
- value: 1
- },
- {
- label: "下单失败",
- value: 2
- },
- {
- label: "订单取消",
- value: 3
- },
- ]
- }
- },
- {
- label: "通知状态",
- prop: "notifyStatus",
- component: {
- name: "el-select",
- props: {
- clearable: true
- },
- options: [
- {
- label: "未通知",
- value: 0
- },
- {
- label: "已通知",
- value: 1
- },
- {
- label: "通知失败",
- value: 2
- }
- ]
- }
- },
- {
- label: "日期范围",
- prop: "createTime",
- component: {
- name: "el-date-picker",
- props: {
- style: { width: "360px" },
- type: "datetimerange",
- unlinkPanels: true,
- valueFormat: "YYYY-MM-DD HH:mm:ss",
- shortcuts: [
- {
- text: '今天',
- value: () => {
- return [dayjs().startOf('day'), dayjs().endOf('day')]
- }
- },
- {
- text: '昨天',
- value: () => {
- return [dayjs().subtract(1, 'day').startOf('day'), dayjs().subtract(1, 'day').endOf('day')]
- }
- },
- {
- text: '近三天',
- value: () => {
- return [dayjs().subtract(2, 'day').startOf('day'), dayjs().endOf('day')]
- }
- },
- {
- text: '近七天',
- value: () => {
- return [dayjs().subtract(6, 'day').startOf('day'), dayjs().endOf('day')]
- }
- },
- {
- text: '近一个月',
- value: () => {
- return [dayjs().startOf('month'), dayjs().endOf('month')]
- }
- },
- ],
- onChange() { }
- }
- }
- }
- ]);
- // cl-upsert
- const Upsert = useUpsert({
- dialog: {
- title: "标记成功"
- },
- async onInfo(data, { done, next }) {
- const newData = await next(data);
- newData.status = 1;
- done(newData);
- },
- items: [
- {
- label: "订单号",
- prop: "orderNo",
- required: true,
- component: {
- name: "el-input",
- props: {
- disabled: true
- }
- }
- },
- {
- prop: "status",
- label: "订单状态",
- component: {
- name: "el-select",
- props: {
- disabled: true
- },
- options: [
- {
- label: "待支付",
- value: 0
- },
- {
- label: "支付成功",
- value: 1
- },
- {
- label: "下单失败",
- value: 2
- },
- {
- label: "订单取消",
- value: 3
- },
- ]
- },
- required: true
- },
- {
- prop: "traceNo",
- label: "交易号",
- component: {
- name: "el-input"
- },
- required: true
- },
- {
- prop: "date",
- label: "付款时间",
- component: {
- name: "el-date-picker",
- props: { type: "datetime", valueFormat: "YYYY-MM-DD HH:mm:ss" }
- },
- required: true
- },
- {
- prop: "remark",
- label: "备注",
- component: { name: "el-input", props: { type: "textarea", rows: 4 } }
- }
- ]
- });
- // cl-table
- const Table = useTable({
- autoHeight: false,
- columns: [
- () => {
- return {
- label: "#",
- type: "expand",
- prop: "detail"
- };
- },
- { prop: "orderNo", label: "订单号", showOverflowTooltip: true, width: 120 },
- { prop: "outOrderNo", label: "商户订单号", showOverflowTooltip: true, width: 120 },
- { prop: "traceNo", label: "交易号", showOverflowTooltip: true, width: 120 },
- {
- prop: "mchId", label: "商户号", hidden: !checkPerm(service.dj.order.permission.mch), width: 90
- },
- {
- prop: "amount",
- label: "金额",
- width: 90,
- formatter(row) {
- return (+row.amount).toFixed(2);
- }
- },
- {
- prop: "charge",
- label: "手续费",
- width: 90,
- formatter(row) {
- return (+row.charge).toFixed(2);
- }
- },
- {
- prop: "currency",
- label: "货币"
- },
- // { prop: "date", label: "付款时间" },
- {
- prop: "status",
- label: "订单状态",
- dict: [
- { label: "待支付", value: 0, color: "#909399" },
- { label: "支付成功", value: 1, color: "#67C23A" },
- { label: "下单失败", value: 2, color: "#F56C6C" },
- { label: "订单取消", value: 3, color: "#F56C6C" }
- ], width: 90
- },
- {
- prop: "notifyStatus",
- label: "通知状态",
- dict: [
- { label: "未通知", value: 0, color: "#909399" },
- { label: "已通知", value: 1, color: "#67C23A" },
- { label: "通知失败", value: 2, color: "#F56C6C" }
- ], width: 90
- },
- { prop: "payType", label: "支付方式", showOverflowTooltip: true, width: 90 },
- {
- prop: "code", label: "通道编码", hidden: !checkPerm(service.dj.order.permission.code), width: 120
- },
- { prop: "createTime", label: "创建时间", width: 155 },
- // { prop: "remark", label: "备注", showOverflowTooltip: true },
- {
- type: "op",
- width: checkPerm(service.dj.order.permission.update) ? 210 : 120,
- buttons({ scope }) {
- const btns = [];
- if (checkPerm(service.dj.order.permission.update)) {
- btns.push({
- label: "标记成功",
- type: "danger",
- onClick({ scope }: any) {
- Upsert.value?.edit(scope.row);
- }
- });
- }
- if (+scope.row.status === 1 || +scope.row.status === 3) {
- // if (checkPerm(service.dj.order.permission.toRefund)) {
- // btns.push({
- // label: "退款",
- // type: "danger",
- // async onClick({ scope }: any) {
- // openRefund(scope.row)
- // }
- // });
- // }
- if (checkPerm(service.dj.order.permission.notify)) {
- btns.push({
- label: "补发通知",
- type: "success",
- async onClick({ scope }: any) {
- const { status, msg = "" } = await service.dj.order.notify({
- id: scope.row.id
- });
- if (+status === 1) {
- ElMessage.success("补发通知成功!");
- Crud.value?.refresh();
- } else {
- ElMessage.error("通知失败,失败原因:" + JSON.stringify(msg));
- }
- }
- });
- }
- } else {
- if (checkPerm(service.dj.order.permission.query)) {
- btns.push({
- label: "API查单",
- type: "primary",
- async onClick({ scope }: any) {
- try {
- const data = await service.dj.order.query({ id: scope.row.id });
- if (+data.status === 0 || +data.status === 2) {
- ElMessage.warning("订单未支付,请稍后查询");
- } else {
- ElMessage.success("订单支付成功,已刷新状态!");
- Crud.value?.refresh();
- }
- } catch (e) {
- ElMessage.warning("订单未支付,请稍后查询");
- }
- }
- });
- }
- }
- return btns;
- }
- }
- ]
- });
- // cl-crud
- const Crud = useCrud(
- {
- service: service.dj.order,
- async onRefresh(params, { next, render }) {
- const { list, pagination } = await next({
- order: "createTime",
- sort: "desc",
- ...params
- });
- if (showSummary.value) {
- const { num1, num2, num3, num4, num5 } = (
- await service.dj.order.summary(params)
- )[0];
- summary.value.num1 = +num1;
- summary.value.num2 = +num2;
- summary.value.num3 = +num3;
- summary.value.num4 = +num4 > 0 ? (+num3 / +num4) * 100 : 0;
- summary.value.num5 = +num5;
- }
- render(list, pagination);
- }
- },
- (app) => {
- app.refresh(filterParam.value);
- }
- );
- </script>
- <style lang="scss">
- .orderList {
- .el-descriptions {
- .el-descriptions__label {
- width: 120px !important;
- }
- }
- }
- .desc .el-descriptions__label {
- min-width: 115px;
- }
- .tooltip {
- max-width: 100px !important;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- </style>
|