|
|
@@ -23,6 +23,9 @@
|
|
|
background-color: #fff;
|
|
|
height: 24px;
|
|
|
}
|
|
|
+.order-detail{
|
|
|
+ margin-left: 20px;
|
|
|
+}
|
|
|
</style>
|
|
|
<template>
|
|
|
<div class="system-container layout-padding">
|
|
|
@@ -41,24 +44,91 @@
|
|
|
<template #extraRight></template>-->
|
|
|
</ext-query-form>
|
|
|
|
|
|
- <ext-table
|
|
|
- class="page-content"
|
|
|
+ <el-table
|
|
|
+ border
|
|
|
+ stripe="stripe"
|
|
|
:height="state.tableData.height"
|
|
|
- :data-list="state.tableData.data"
|
|
|
- :columns="state.columns"
|
|
|
- :border="true"
|
|
|
- :loading="state.tableData.loading">
|
|
|
- </ext-table>
|
|
|
+ highlight-current-row
|
|
|
+ current-row-key="id"
|
|
|
+ row-key="id"
|
|
|
+ @on-row-click="handleRowClick('view',$event)"
|
|
|
+ :data="state.tableData.data"
|
|
|
+ v-loading="state.tableData.loading">
|
|
|
+ <template #empty>
|
|
|
+ <el-empty></el-empty>
|
|
|
+ </template>
|
|
|
+ <el-table-column
|
|
|
+ v-for="field in state.columns"
|
|
|
+ :key="field.prop"
|
|
|
+ :type="field.type"
|
|
|
+ :label="field.label"
|
|
|
+ :column-key="field.prop"
|
|
|
+ :width="field.width"
|
|
|
+ :min-width="field.minWidth"
|
|
|
+ :fixed="field.fixed"
|
|
|
+ :sortable="field.sortable"
|
|
|
+ :show-overflow-tooltip="!field.fixed&&field.width>150">
|
|
|
+
|
|
|
+ <template #default="{row}">
|
|
|
+ <template v-if="field.type==='expand'">
|
|
|
+ <div class="order-detail">
|
|
|
+ <el-table
|
|
|
+ border
|
|
|
+ :data="row.detail"
|
|
|
+ stripe="stripe">
|
|
|
+ <el-table-column width="120" label="项目" prop="name"></el-table-column>
|
|
|
+ <el-table-column width="120" label="时长" prop="seconds"></el-table-column>
|
|
|
+ <el-table-column width="120" label="单价" prop="price"></el-table-column>
|
|
|
+ <el-table-column width="120" label="费用" prop="amount"></el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-else-if="field.prop==='discountType'">
|
|
|
+ <ext-d-label type="Activity.discountType" :model-value="row[field.prop]"></ext-d-label>
|
|
|
+ </template>
|
|
|
+ <template v-else-if="field.prop==='cardType'">
|
|
|
+ <ext-d-label type="OrderCard.type" :model-value="row[field.prop]"></ext-d-label>
|
|
|
+ </template>
|
|
|
+ <template v-else-if="field.prop==='invoiceStatus'">
|
|
|
+ <ext-d-label type="Invoice.status" :model-value="row[field.prop]"></ext-d-label>
|
|
|
+ </template>
|
|
|
+ <template v-else-if="field.prop==='openType'">
|
|
|
+ <ext-d-label type="Order.openType" :model-value="row[field.prop]"></ext-d-label>
|
|
|
+ </template>
|
|
|
+ <template v-else-if="field.prop==='orderStatus'">
|
|
|
+ <ext-d-label type="Order.status" :model-value="row[field.prop]"></ext-d-label>
|
|
|
+ </template>
|
|
|
+ <template v-else-if="field.prop==='payStatus'">
|
|
|
+ <ext-d-label type="Order.pay" :model-value="row[field.prop]"></ext-d-label>
|
|
|
+ </template>
|
|
|
+ <template v-else-if="['prepayMoney','amount','amountReceivable','amountReceived','cardBalance','coinMoney','discountAmount','discountMoney'].includes(field.prop)">
|
|
|
+ {{ u.fmt.fmtMoney(row[row.prop]) }}
|
|
|
+ </template>
|
|
|
+ <template v-else-if="field.prop==='idleRemainTime'||field.prop==='operationRemainTime'">
|
|
|
+ {{ u.fmt.fmtDuration(row[field.prop]) }}
|
|
|
+ </template>
|
|
|
+ <template v-else-if="field.prop==='createTime'">
|
|
|
+ {{ u.fmt.fmtDateTime(row[field.prop]) }}
|
|
|
+ </template>
|
|
|
+ <template v-else-if="field.prop==='updateTime'">
|
|
|
+ {{ u.fmt.fmtDateTime(row[field.prop]) }}
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <div>{{ row[field.prop] }}</div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
|
|
|
<ext-page class="page-pager" v-model:value="state.pageQuery" @change="loadData(false)"/>
|
|
|
</el-card>
|
|
|
</div>
|
|
|
- <WashOrderDialog ref="washOrderDialogRef" @refresh="loadData(true)"/>
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts" name="WashOrderList">
|
|
|
-import {defineAsyncComponent, reactive, onMounted, onBeforeMount, ref, getCurrentInstance,nextTick,onBeforeUnmount} from 'vue';
|
|
|
-import {$body,$get} from "/@/utils/request";
|
|
|
+import {defineAsyncComponent, reactive, onMounted, onBeforeMount, ref, getCurrentInstance, nextTick, onBeforeUnmount} from 'vue';
|
|
|
+import {$body, $get} from "/@/utils/request";
|
|
|
import u from '/@/utils/u'
|
|
|
import {Msg} from "/@/utils/message";
|
|
|
import {Session} from "/@/utils/storage";
|
|
|
@@ -67,11 +137,10 @@ const {proxy}: any = getCurrentInstance();
|
|
|
|
|
|
import ExtPage from '/@/components/form/ExtPage.vue'
|
|
|
import ExtQueryForm from "/@/components/form/ExtQueryForm.vue";
|
|
|
-import ExtTable from "/@/components/form/ExtTable.vue";
|
|
|
|
|
|
import mittBus from '/@/utils/mitt';
|
|
|
|
|
|
-import {ElButton} from 'element-plus'
|
|
|
+import ExtDLabel from "/@/components/form/ExtDLabel.vue";
|
|
|
|
|
|
|
|
|
const WashOrderDialog = defineAsyncComponent(() => import("/@/views/admin/ordering/dialog.vue"));
|
|
|
@@ -84,87 +153,110 @@ const washOrderDialogRef = ref();
|
|
|
const state = reactive({
|
|
|
formQuery: {},
|
|
|
pageQuery: {
|
|
|
- pageIndex: 1,
|
|
|
+ pageNum: 1,
|
|
|
pageSize: 10,
|
|
|
total: 0
|
|
|
},
|
|
|
tableData: {
|
|
|
- height:500,
|
|
|
- data: [] as Array < any >,
|
|
|
+ height: 500,
|
|
|
+ data: [] as Array<any>,
|
|
|
loading: false
|
|
|
},
|
|
|
importConfig: {},
|
|
|
exportConfig: {},
|
|
|
columns: [
|
|
|
- {type: 'selection', width: 60, align: 'center', fixed: 'left'},
|
|
|
- {label: '消费总额,等于各单项费用之和(单位分)', prop: 'amount', query: true, type: '', resizable: true},
|
|
|
- {label: '应收金额,如果大于预付金额,则限制为预付金额并关机,否则等于消费总金额(单位分)', prop: 'amountReceivable', query: true, type: '', resizable: true},
|
|
|
- {label: '实收金额等于应收金额乘会员折扣(单位分)', prop: 'amountReceived', query: true, type: '', resizable: true},
|
|
|
- {label: '卡内余额(仅限刷储值卡的订单有效,普通卡为总是为0)', prop: 'cardBalance', query: true, type: '', resizable: true},
|
|
|
- {label: '卡过期时间,从1970年开始的时间戳(仅限刷储值卡的订单有效,普通卡为总是为0)', prop: 'cardExpired', query: true, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDate(val)}},
|
|
|
- {label: '卡内码,卡出厂的时候厂家写入的ID(仅限刷卡订单)', prop: 'cardId', query: true, type: 'text', resizable: true},
|
|
|
- {label: '卡串号,印刷在卡的表面,通过电脑上的卡管理工具写入卡内。(仅限刷卡订单)', prop: 'cardSn', query: true, type: 'text', resizable: true},
|
|
|
- {label: '卡类型(仅限刷卡订单,1表示普通卡,2表示储值卡)', prop: 'cardType', query: true, type: '', resizable: true},
|
|
|
- {label: '关机方式:button维护按钮,network网络命令,no_balance超过预设金额,idle_timeout设备空闲超时,operation_timeout操作超时,card刷卡。注意:为空表示还没有关机,正在使用', prop: 'closeType', query: true, type: 'text', resizable: true},
|
|
|
- {label: '投币的累计金额(仅限刷卡订单,单位分)', prop: 'coinMoney', query: true, type: '', resizable: true},
|
|
|
- {label: '投币的次数仅限刷卡订单', prop: 'coinNum', query: true, type: '', resizable: true},
|
|
|
- {label: '', prop: 'createTime', query: true, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDate(val)}},
|
|
|
- {label: '费用明细:name 名称 price 单价(单位分) seconds 时长(单位秒) amount 费用(单位分) space⻋位或场地,water清水,foam泡沫,cleaner吸尘,tap水龙头,user_ext用户扩展,消毒或吹干等功能,coat镀膜,blow吹气', prop: 'detail', query: true, type: 'text', resizable: true},
|
|
|
- {label: '设备名称', prop: 'deviceName', query: true, type: 'text', resizable: true},
|
|
|
- {label: '优惠金额(分)', prop: 'discountAmount', query: true, type: '', resizable: true},
|
|
|
- {label: '优惠金额等于消费总额减去实收金额(单位分)', prop: 'discountMoney', query: true, type: '', resizable: true},
|
|
|
- {label: '优惠方式:RechargeRights-充值权益 Coupon-优惠券', prop: 'discountType', query: true, type: 'text', resizable: true},
|
|
|
- {label: '结束时间', prop: 'endTime', query: true, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDate(val)}},
|
|
|
- {label: '设备空闲关机倒计时剩余时间(单位秒),开机后从idle_timeout开始每秒减1,见到0关机,关机原因close_type=idle_time(递减过程中按任意功能键,重新开始从idle_timeout递减)', prop: 'idleRemainTime', query: true, type: '', resizable: true},
|
|
|
- {label: '发票状态:0-待开票 1-已开票 2-已作废(用不上) 3-开票中', prop: 'invoiceStatus', query: true, type: '', resizable: true},
|
|
|
- {label: '会员折扣比例(0-100,100表示不享受折扣,95表示9.5折优惠)', prop: 'memberDiscount', query: true, type: '', resizable: true},
|
|
|
- {label: '开机方式:button维护按钮,network网络命令,coin投币,card刷卡', prop: 'openType', query: true, type: 'text', resizable: true},
|
|
|
- {label: '订单操作剩余操作时间(单位秒),开机后从operation_timeout开始每秒减1,减到0关机,关机原因close_type=operation_timeout', prop: 'operationRemainTime', query: true, type: '', resizable: true},
|
|
|
- {label: '订单号,和开机命令的order_id相同,如果使用按钮快速开机,order_id是空字符串', prop: 'orderId', query: true, type: 'text', resizable: true},
|
|
|
- {label: '本机订单号', prop: 'orderIdLocal', query: true, type: 'text', resizable: true},
|
|
|
- {label: '订单状态:-1:未知,0-开机,1:成功,2:失败,3:取消', prop: 'orderStatus', query: true, type: '', resizable: true},
|
|
|
- {label: '支付状态:0:未支付,1:已支付', prop: 'payStatus', query: true, type: '', resizable: true},
|
|
|
- {label: '本次开机的预付金额(单位分,本次开机最大消费金额限制)', prop: 'prepayMoney', query: true, type: '', resizable: true},
|
|
|
- {label: '产品key', prop: 'productKey', query: true, type: 'text', resizable: true},
|
|
|
- {label: '开始时间', prop: 'startTime', query: true, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDate(val)}},
|
|
|
- {label: '', prop: 'stationId', query: true, type: 'text', resizable: true},
|
|
|
- {label: '', prop: 'stopReason', query: true, type: 'text', resizable: true},
|
|
|
- {label: '', prop: 'updateTime', query: true, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDate(val)}},
|
|
|
- { label: '操作', prop: 'action', type: 'render', width: 180, align: 'center', fixed: 'right',
|
|
|
- render: (h: any, row: any) => {
|
|
|
- return (
|
|
|
- h('div', null, [
|
|
|
- proxy.$auth('washOrder.modify') ?
|
|
|
- h(ElButton, {
|
|
|
- type: 'warning',
|
|
|
- text: true,
|
|
|
- size: 'small',
|
|
|
- onClick: () => {
|
|
|
- handleRowClick('edit', row)
|
|
|
- }
|
|
|
- }, () => '编辑') : '',
|
|
|
- proxy.$auth('washOrder.remove') ?
|
|
|
- h(ElButton, {
|
|
|
- type: 'danger',
|
|
|
- text: true,
|
|
|
- size: 'small',
|
|
|
- onClick: () => {
|
|
|
- handleRowDelete(row)
|
|
|
- }
|
|
|
- }, () => '删除') : '',
|
|
|
- ])
|
|
|
- )
|
|
|
- }
|
|
|
- }
|
|
|
+ {type: 'expand', width: 60, align: 'center', fixed: 'left'},
|
|
|
+ {width: 260, label: '订单号', prop: 'orderId', query: true, type: 'text', resizable: true, fixed: 'left'},
|
|
|
+ {width: 160, label: '消费总额', prop: 'amount', query: false, resizable: true, fixed: 'left'},
|
|
|
+ {width: 160, label: '应收金额', prop: 'amountReceivable', query: false, type: '', resizable: true},
|
|
|
+ {width: 160, label: '实收金额', prop: 'amountReceived', query: false, type: 'text', resizable: true},
|
|
|
+ {width: 160, label: '卡内余额', prop: 'cardBalance', query: false, type: 'text', resizable: true},
|
|
|
+ {
|
|
|
+ width: 160, label: '卡过期时间',
|
|
|
+ prop: 'cardExpired',
|
|
|
+ query: true,
|
|
|
+ sortable: 'custom',
|
|
|
+ type: 'datetime',
|
|
|
+ resizable: true,
|
|
|
+ conf: {format: (val: any) => u.fmt.fmtDateTime(val)}
|
|
|
+ },
|
|
|
+ {width: 160, label: '卡内码', prop: 'cardId', query: false, type: 'text', resizable: true},
|
|
|
+ {width: 160, label: '卡串号', prop: 'cardSn', query: false, type: 'text', resizable: true},
|
|
|
+ {width: 160, label: '卡类型', prop: 'cardType', query: false, type: '', resizable: true},
|
|
|
+ {
|
|
|
+ width: 160, label: '关机方式',
|
|
|
+ prop: 'closeType',
|
|
|
+ query: true,
|
|
|
+ type: 'dict',
|
|
|
+ conf: {dict: 'Order.closeType'},
|
|
|
+ resizable: true
|
|
|
+ },
|
|
|
+ {width: 160, label: '投币的累计金额', prop: 'coinMoney', query: false, type: 'text', resizable: true},
|
|
|
+ {width: 160, label: '投币的次数', prop: 'coinNum', query: false, type: 'text', resizable: true},
|
|
|
+ {width: 160, label: '开单时间', prop: 'createTime', query: false, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDateTime(val)}},
|
|
|
+ // {
|
|
|
+ // width:160,label: '费用明细',
|
|
|
+ // prop: 'detail',
|
|
|
+ // query: true,
|
|
|
+ // type: 'text',
|
|
|
+ // resizable: true
|
|
|
+ // },
|
|
|
+
|
|
|
+ {width: 160, label: '设备名称', prop: 'deviceName', query: false, type: 'text', resizable: true},
|
|
|
+ {width: 160, label: '优惠金额', prop: 'discountAmount', query: false, type: '', resizable: true},
|
|
|
+ {width: 160, label: '优惠金额', prop: 'discountMoney', query: false, type: '', resizable: true},
|
|
|
+ {width: 160, label: '优惠方式', prop: 'discountType', query: true, type: 'dict', conf: {dict: 'Activity.discountType'}, resizable: true},
|
|
|
+ {width: 160, label: '结束时间', prop: 'endTime', query: false, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDateTime(val)}},
|
|
|
+ {
|
|
|
+ width: 160, label: '设备空闲关机倒计时剩余时间',
|
|
|
+ prop: 'idleRemainTime',
|
|
|
+ query: true,
|
|
|
+ type: 'text',
|
|
|
+ resizable: true
|
|
|
+ },
|
|
|
+ {width: 160, label: '发票状态', prop: 'invoiceStatus', query: true, type: 'dict', conf: {dict: 'Invoice.status'}, resizable: true},
|
|
|
+ {width: 160, label: '会员折扣比例', prop: 'memberDiscount', query: false, type: 'text', resizable: true},
|
|
|
+ {width: 160, label: '开机方式', prop: 'openType', query: true, type: 'dict', conf: {dict: 'Order.openType'}, resizable: true},
|
|
|
+ {width: 160, label: '订单操作剩余操作时间(单位秒)', prop: 'operationRemainTime', query: false, type: 'text', resizable: true},
|
|
|
+ {width: 160, label: '本机订单号', prop: 'orderIdLocal', query: false, type: 'text', resizable: true},
|
|
|
+ {width: 160, label: '订单状态', prop: 'orderStatus', query: true, type: 'dict', conf: {dict: 'Order.status'}, resizable: true},
|
|
|
+ {width: 160, label: '支付状态', prop: 'payStatus', query: true, type: 'dict', conf: {dict: 'Order.pay'}, resizable: true},
|
|
|
+ {width: 160, label: '本次开机的预付金额', prop: 'prepayMoney', query: true, type: '', resizable: true},
|
|
|
+ {width: 160, label: '产品key', prop: 'productKey', query: true, type: 'text', resizable: true},
|
|
|
+ {width: 160, label: '开始时间', prop: 'startTime', query: false, sortable: 'custom', type: 'datetime', resizable: true, conf: {format: (val: any) => u.fmt.fmtDate(val)}},
|
|
|
+ {width: 160, label: '站点ID', prop: 'stationId', query: true, type: 'text', resizable: true},
|
|
|
+ {width: 160, label: '停机原因', prop: 'stopReason', query: false, type: 'text', resizable: true},
|
|
|
+ {
|
|
|
+ width: 160,
|
|
|
+ label: '更新时间',
|
|
|
+ fixed: 'right',
|
|
|
+ prop: 'updateTime',
|
|
|
+ query: false,
|
|
|
+ sortable: 'custom',
|
|
|
+ type: 'datetime',
|
|
|
+ resizable: true,
|
|
|
+ conf: {format: (val: any) => u.fmt.fmtDate(val)}
|
|
|
+ },
|
|
|
],
|
|
|
})
|
|
|
|
|
|
|
|
|
// 监听双向绑定 modelValue 的变化
|
|
|
// watch(
|
|
|
-// () => state.pageIndex,
|
|
|
+// () => state.pageNum,
|
|
|
// () => {
|
|
|
-//
|
|
|
+// //:' +
|
|
|
+// 'name 名称 price 单价(单位分) ' +
|
|
|
+// 'seconds 时长(单位秒) ' +
|
|
|
+// 'amount 费用(单位分)' +
|
|
|
+// ' space⻋位或场地,' +
|
|
|
+// 'water清水,' +
|
|
|
+// 'foam泡沫,' +
|
|
|
+// 'leaner吸尘,' +
|
|
|
+// 'tap水龙头,' +
|
|
|
+// 'user_ext用户扩展,消毒或吹干等功能,' +
|
|
|
+// 'coat镀膜,' +
|
|
|
+// 'blow吹气
|
|
|
// }
|
|
|
// );
|
|
|
|
|
|
@@ -187,18 +279,18 @@ onBeforeMount(() => {
|
|
|
onMounted(() => {
|
|
|
loadData();
|
|
|
|
|
|
- nextTick(()=>{
|
|
|
+ nextTick(() => {
|
|
|
let bodyHeight = document.body.clientHeight;
|
|
|
let queryHeight = queryRef.value.$el.clientHeight;
|
|
|
state.tableData.height = bodyHeight - queryHeight - 220
|
|
|
})
|
|
|
|
|
|
- mittBus.on("washOrder.refresh",()=>{
|
|
|
+ mittBus.on("washOrder.refresh", () => {
|
|
|
loadData();
|
|
|
})
|
|
|
});
|
|
|
|
|
|
-onBeforeUnmount(()=>{
|
|
|
+onBeforeUnmount(() => {
|
|
|
mittBus.off("washOrder.refresh")
|
|
|
})
|
|
|
|
|
|
@@ -207,16 +299,33 @@ onBeforeUnmount(()=>{
|
|
|
// 初始化表格数据
|
|
|
const loadData = (refresh: boolean = false) => {
|
|
|
if (refresh) {
|
|
|
- state.pageQuery.pageIndex = 1;
|
|
|
+ state.pageQuery.pageNum = 1;
|
|
|
}
|
|
|
state.tableData.loading = true;
|
|
|
$body(`/washOrder/list`, {...state.formQuery, ...state.pageQuery}).then((res: any) => {
|
|
|
- let {list, count} = res;
|
|
|
+ let {list, total} = res;
|
|
|
+
|
|
|
+ list.forEach((item:any)=>{
|
|
|
+ if(item.detail){
|
|
|
+ let parse = JSON.parse(item.detail);
|
|
|
+ item.detail = parse.filter((k:any)=>k.amount>0||k.seconds>0).map((s:any)=>{
|
|
|
+ return {
|
|
|
+ name:u.fmt.fmtDict(s.name,'Order.feeType'),
|
|
|
+ seconds:u.fmt.fmtDuration(s.seconds),
|
|
|
+ price:u.fmt.fmtMoney(s.price),
|
|
|
+ amount:u.fmt.fmtMoney(s.amount),
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }else{
|
|
|
+ item.detail={}
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
state.tableData.data = list;
|
|
|
- state.pageQuery.total = count;
|
|
|
+ state.pageQuery.total = total;
|
|
|
state.tableData.loading = false;
|
|
|
}).catch(e => {
|
|
|
- console.error(e)
|
|
|
+ //console.error(e)
|
|
|
state.tableData.loading = false;
|
|
|
})
|
|
|
};
|