1184 lines
36 KiB
Vue
1184 lines
36 KiB
Vue
<template>
|
||
<div class="app-container">
|
||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="auto">
|
||
<el-form-item label="微信支付单号" prop="transactionId">
|
||
<el-input
|
||
v-model="queryParams.transactionId"
|
||
placeholder="微信支付单号"
|
||
clearable
|
||
@keyup.enter.native="handleQuery"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="订单号" prop="orderId" label-width="auto">
|
||
<el-input
|
||
v-model="queryParams.orderId"
|
||
placeholder="请输入订单号"
|
||
clearable
|
||
@keyup.enter.native="handleQuery"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="用户" prop="name" label-width="auto">
|
||
<el-input
|
||
v-model="queryParams.name"
|
||
placeholder="请输入用户"
|
||
clearable
|
||
@keyup.enter.native="handleQuery"
|
||
>
|
||
</el-input>
|
||
</el-form-item>
|
||
<el-form-item label="下单手机号" prop="phone" label-width="auto">
|
||
<el-input
|
||
v-model="queryParams.phone"
|
||
placeholder="请输入下单手机号"
|
||
clearable
|
||
@keyup.enter.native="handleQuery"
|
||
>
|
||
</el-input>
|
||
</el-form-item>
|
||
<el-form-item label="商品" prop="transactionId" label-width="auto">
|
||
<el-input
|
||
v-model="queryParams.transactionId"
|
||
placeholder="请输入商品"
|
||
clearable
|
||
@keyup.enter.native="handleQuery"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="订单状态" prop="mark" label-width="auto">
|
||
<el-input
|
||
v-model="queryParams.mark"
|
||
placeholder="请输入订单状态"
|
||
clearable
|
||
@keyup.enter.native="handleQuery"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="师傅" prop="mark" label-width="auto">
|
||
<el-input
|
||
v-model="queryParams.mark"
|
||
placeholder="请输入师傅"
|
||
clearable
|
||
@keyup.enter.native="handleQuery"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="总价" prop="priceRange" label-width="auto">
|
||
<el-input
|
||
v-model="queryParams.priceMin"
|
||
placeholder="最低价"
|
||
style="width: 100px; margin-right: 10px;"
|
||
type="number"
|
||
min="0"
|
||
clearable
|
||
/>
|
||
<span style="margin: 0 5px;">-</span>
|
||
<el-input
|
||
v-model="queryParams.priceMax"
|
||
placeholder="最高价"
|
||
style="width: 100px;"
|
||
type="number"
|
||
min="0"
|
||
clearable
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="支付金额" prop="priceRange">
|
||
<el-input
|
||
v-model="queryParams.priceMin"
|
||
placeholder="最低价"
|
||
style="width: 100px; margin-right: 10px;"
|
||
type="number"
|
||
min="0"
|
||
clearable
|
||
/>
|
||
<span style="margin: 0 5px;">-</span>
|
||
<el-input
|
||
v-model="queryParams.priceMax"
|
||
placeholder="最高价"
|
||
style="width: 100px;"
|
||
type="number"
|
||
min="0"
|
||
clearable
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="支付时间">
|
||
<el-date-picker
|
||
v-model="daterangePayTime"
|
||
style="width: 240px"
|
||
value-format="yyyy-MM-dd"
|
||
type="daterange"
|
||
range-separator="-"
|
||
start-placeholder="开始日期"
|
||
end-placeholder="结束日期"
|
||
></el-date-picker>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="创建时间">
|
||
<el-date-picker
|
||
v-model="daterangePayTime"
|
||
style="width: 240px"
|
||
value-format="yyyy-MM-dd"
|
||
type="daterange"
|
||
range-separator="-"
|
||
start-placeholder="开始日期"
|
||
end-placeholder="结束日期"
|
||
></el-date-picker>
|
||
</el-form-item>
|
||
|
||
|
||
<el-form-item>
|
||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<el-row :gutter="10" class="mb8">
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="primary"
|
||
plain
|
||
icon="el-icon-plus"
|
||
size="mini"
|
||
@click="handleAdd"
|
||
v-hasPermi="['system:Order:add']"
|
||
>新增</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="success"
|
||
plain
|
||
icon="el-icon-edit"
|
||
size="mini"
|
||
:disabled="single"
|
||
@click="handleUpdate"
|
||
v-hasPermi="['system:Order:edit']"
|
||
>修改</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="danger"
|
||
plain
|
||
icon="el-icon-delete"
|
||
size="mini"
|
||
:disabled="multiple"
|
||
@click="handleDelete"
|
||
v-hasPermi="['system:Order:remove']"
|
||
>删除</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="warning"
|
||
plain
|
||
icon="el-icon-download"
|
||
size="mini"
|
||
@click="handleExport"
|
||
v-hasPermi="['system:Order:export']"
|
||
>导出</el-button>
|
||
</el-col>
|
||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||
</el-row>
|
||
|
||
<el-table
|
||
v-loading="loading"
|
||
:data="OrderList"
|
||
@selection-change="handleSelectionChange"
|
||
border
|
||
stripe
|
||
highlight-current-row
|
||
style="width: 100%"
|
||
:row-key="row => row.id"
|
||
>
|
||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||
<el-table-column label="ID" align="center" width="55" prop="id" fixed="left" />
|
||
<el-table-column label="订单号" align="center" prop="orderId" width="130" show-overflow-tooltip />
|
||
<el-table-column label="用户" align="center" width="85" prop="uname" />
|
||
<el-table-column label="商品" align="center" prop="productName" show-overflow-tooltip />
|
||
<el-table-column label="姓名" align="center" width="80" prop="name"/>
|
||
|
||
<el-table-column label="电话" align="center" width="120" prop="phone"/>
|
||
|
||
|
||
<el-table-column label="总价" width="100" align="right" prop="totalPrice" >
|
||
<template slot-scope="scope">
|
||
<span class="price-tag">¥{{ (scope.row.totalPrice != null ? scope.row.totalPrice : 0).toFixed(2) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="支付金额" width="100" align="right" prop="payPrice" >
|
||
<template slot-scope="scope">
|
||
<span class="pay-price-tag">¥{{ (scope.row.payPrice != null ? scope.row.payPrice : 0).toFixed(2) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="抵扣金额" width="100" align="right" prop="deduction" >
|
||
<template slot-scope="scope">
|
||
<span class="discount-tag">¥{{ (scope.row.deduction != null ? scope.row.deduction : 0).toFixed(2) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="支付时间" align="center" prop="payTime" width="120">
|
||
<template slot-scope="scope">
|
||
<span>{{ parseTime(scope.row.payTime, '{y}-{m}-{d}') }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="订单状态" align="center" prop="status">
|
||
<template slot-scope="scope">
|
||
<dict-tag :options="dict.type.order_status" :value="scope.row.status"/>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="创建时间" align="center" prop="createdAt" width="120">
|
||
<template slot-scope="scope">
|
||
<span>{{ parseTime(scope.row.createdAt, '{y}-{m}-{d}') }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="通话记录" align="center" width="100">
|
||
<template slot-scope="scope">
|
||
<div class="record-box" @click="showRecordDetails(scope.row, 'call')">
|
||
<el-button type="text" class="expand-button">
|
||
<span class="record-count">{{ scope.row.thjl || 0 }}</span>
|
||
<i class="el-icon-arrow-right"></i>
|
||
</el-button>
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="录音文件" align="center" width="100">
|
||
<template slot-scope="scope">
|
||
<div class="record-box" @click="showRecordDetails(scope.row, 'audio')">
|
||
<el-button type="text" class="expand-button">
|
||
<span class="record-count">{{ scope.row.lywj || 0 }}</span>
|
||
<i class="el-icon-arrow-right"></i>
|
||
</el-button>
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="接单记录" align="center" width="100">
|
||
<template slot-scope="scope">
|
||
<div class="record-box" @click="showRecordDetails(scope.row, 'receive')">
|
||
<el-button type="text" class="expand-button">
|
||
<span class="record-count">{{ scope.row.jdjl || 0 }}</span>
|
||
<i class="el-icon-arrow-right"></i>
|
||
</el-button>
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="通知记录" align="center" width="100">
|
||
<template slot-scope="scope">
|
||
<div class="record-box" @click="showRecordDetails(scope.row, 'notify')">
|
||
<el-button type="text" class="expand-button">
|
||
<span class="record-count">{{ scope.row.tzjl || 0 }}</span>
|
||
<i class="el-icon-arrow-right"></i>
|
||
</el-button>
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<!-- 修改评价列,点击时弹出对话框而非展开行 -->
|
||
<el-table-column label="评价" align="center" width="100">
|
||
<template slot-scope="scope">
|
||
<div class="comment-box" @click="showCommentDetails(scope.row)">
|
||
<el-button type="text" class="expand-button">
|
||
<span class="comment-count">{{ scope.row.fwpj || 0 }}</span>
|
||
<i class="el-icon-arrow-right"></i>
|
||
</el-button>
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<!-- 修复操作栏样式,确保按钮是标准圆形 -->
|
||
<el-table-column label="操作" align="center" width="160" fixed="right" class-name="small-padding fixed-width">
|
||
<template slot-scope="scope">
|
||
<div class="button-group" v-if="scope.row.id">
|
||
<el-button
|
||
size="mini"
|
||
type="primary"
|
||
icon="el-icon-edit"
|
||
circle
|
||
@click="handleUpdate(scope.row)"
|
||
v-hasPermi="['system:Order:edit']"
|
||
></el-button>
|
||
<el-button
|
||
size="mini"
|
||
type="danger"
|
||
icon="el-icon-delete"
|
||
circle
|
||
@click="handleDelete(scope.row)"
|
||
v-hasPermi="['system:Order:remove']"
|
||
></el-button>
|
||
<el-dropdown trigger="click" @command="(command) => handleCommand(command, scope.row)">
|
||
<el-button
|
||
size="mini"
|
||
type="info"
|
||
icon="el-icon-more"
|
||
circle
|
||
@click.stop
|
||
></el-button>
|
||
<el-dropdown-menu slot="dropdown">
|
||
<el-dropdown-item command="jdjl" icon="el-icon-notebook-2">接单记录</el-dropdown-item>
|
||
<el-dropdown-item command="lywj" icon="el-icon-headset">录音文件</el-dropdown-item>
|
||
<el-dropdown-item command="tzjl" icon="el-icon-bell">通知记录</el-dropdown-item>
|
||
</el-dropdown-menu>
|
||
</el-dropdown>
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<pagination
|
||
v-show="total>0"
|
||
:total="total"
|
||
:page.sync="queryParams.pageNum"
|
||
:limit.sync="queryParams.pageSize"
|
||
@pagination="getList"
|
||
/>
|
||
|
||
<!-- 添加或修改服务订单对话框 -->
|
||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||
<el-form-item label="主订单号" prop="mainOrderId">
|
||
<el-input v-model="form.mainOrderId" placeholder="请输入主订单号" />
|
||
</el-form-item>
|
||
<el-form-item label="订单号" prop="orderId">
|
||
<el-input v-model="form.orderId" placeholder="请输入订单号" />
|
||
</el-form-item>
|
||
<el-form-item label="微信支付单号" prop="transactionId">
|
||
<el-input v-model="form.transactionId" placeholder="请输入微信支付单号" />
|
||
</el-form-item>
|
||
<el-form-item label="后台下单用户手机号" prop="createPhone">
|
||
<el-input v-model="form.createPhone" placeholder="请输入后台下单用户手机号" />
|
||
</el-form-item>
|
||
<el-form-item label="用户" prop="uid">
|
||
<el-input v-model="form.uid" placeholder="请输入用户" />
|
||
</el-form-item>
|
||
<el-form-item label="商品" prop="productId">
|
||
<el-input v-model="form.productId" placeholder="请输入商品" />
|
||
</el-form-item>
|
||
<el-form-item label="姓名" prop="name">
|
||
<el-input v-model="form.name" placeholder="请输入姓名" />
|
||
</el-form-item>
|
||
<el-form-item label="电话" prop="phone">
|
||
<el-input v-model="form.phone" placeholder="请输入电话" />
|
||
</el-form-item>
|
||
<el-form-item label="地址" prop="address">
|
||
<el-input v-model="form.address" placeholder="请输入地址" />
|
||
</el-form-item>
|
||
<el-form-item label="预约时间-天" prop="makeTime">
|
||
<el-input v-model="form.makeTime" placeholder="请输入预约时间-天" />
|
||
</el-form-item>
|
||
<el-form-item label="预约时间-小时" prop="makeHour">
|
||
<el-input v-model="form.makeHour" placeholder="请输入预约时间-小时" />
|
||
</el-form-item>
|
||
<el-form-item label="数量" prop="num">
|
||
<el-input v-model="form.num" placeholder="请输入数量" />
|
||
</el-form-item>
|
||
<el-form-item label="总价" prop="totalPrice">
|
||
<el-input v-model="form.totalPrice" placeholder="请输入总价" />
|
||
</el-form-item>
|
||
<el-form-item label="商品金额" prop="goodPrice">
|
||
<el-input v-model="form.goodPrice" placeholder="请输入商品金额" />
|
||
</el-form-item>
|
||
<el-form-item label="服务金额" prop="servicePrice">
|
||
<el-input v-model="form.servicePrice" placeholder="请输入服务金额" />
|
||
</el-form-item>
|
||
<el-form-item label="支付金额" prop="payPrice">
|
||
<el-input v-model="form.payPrice" placeholder="请输入支付金额" />
|
||
</el-form-item>
|
||
<el-form-item label="优惠券ID" prop="couponId">
|
||
<el-input v-model="form.couponId" placeholder="请输入优惠券ID" />
|
||
</el-form-item>
|
||
<el-form-item label="抵扣金额" prop="deduction">
|
||
<el-input v-model="form.deduction" placeholder="请输入抵扣金额" />
|
||
</el-form-item>
|
||
<el-form-item label="支付时间" prop="payTime">
|
||
<el-date-picker clearable
|
||
v-model="form.payTime"
|
||
type="date"
|
||
value-format="yyyy-MM-dd"
|
||
placeholder="请选择支付时间">
|
||
</el-date-picker>
|
||
</el-form-item>
|
||
<el-form-item label="1:开始服务 2:暂停服务" prop="isPause">
|
||
<el-input v-model="form.isPause" placeholder="请输入1:开始服务 2:暂停服务" />
|
||
</el-form-item>
|
||
<el-form-item label="备注" prop="mark">
|
||
<el-input v-model="form.mark" placeholder="请输入备注" />
|
||
</el-form-item>
|
||
<el-form-item label="关联地址" prop="addressId">
|
||
<el-input v-model="form.addressId" placeholder="请输入关联地址" />
|
||
</el-form-item>
|
||
<el-form-item label="多规格产品" prop="sku">
|
||
<el-input v-model="form.sku" type="textarea" placeholder="请输入内容" />
|
||
</el-form-item>
|
||
<el-form-item label="师傅ID" prop="workerId">
|
||
<el-input v-model="form.workerId" placeholder="请输入师傅ID" />
|
||
</el-form-item>
|
||
<el-form-item label="转单之后,第一次接单的师傅" prop="firstWorkerId">
|
||
<el-input v-model="form.firstWorkerId" placeholder="请输入转单之后,第一次接单的师傅" />
|
||
</el-form-item>
|
||
<el-form-item label="接单时间" prop="receiveTime">
|
||
<el-date-picker clearable
|
||
v-model="form.receiveTime"
|
||
type="date"
|
||
value-format="yyyy-MM-dd"
|
||
placeholder="请选择接单时间">
|
||
</el-date-picker>
|
||
</el-form-item>
|
||
<el-form-item label="1:已评价 0:未评价" prop="isComment">
|
||
<el-input v-model="form.isComment" placeholder="请输入1:已评价 0:未评价" />
|
||
</el-form-item>
|
||
<el-form-item label="1:已经接单" prop="isAccept">
|
||
<el-input v-model="form.isAccept" placeholder="请输入1:已经接单" />
|
||
</el-form-item>
|
||
<el-form-item label="中间虚拟号" prop="middlePhone">
|
||
<el-input v-model="form.middlePhone" placeholder="请输入中间虚拟号" />
|
||
</el-form-item>
|
||
<el-form-item label="用户手机号" prop="userPhone">
|
||
<el-input v-model="form.userPhone" placeholder="请输入用户手机号" />
|
||
</el-form-item>
|
||
<el-form-item label="师傅手机号" prop="workerPhone">
|
||
<el-input v-model="form.workerPhone" placeholder="请输入师傅手机号" />
|
||
</el-form-item>
|
||
<el-form-item label="${comment}" prop="addressEn">
|
||
<el-input v-model="form.addressEn" placeholder="请输入${comment}" />
|
||
</el-form-item>
|
||
<el-form-item label="${comment}" prop="uidAdmin">
|
||
<el-input v-model="form.uidAdmin" placeholder="请输入${comment}" />
|
||
</el-form-item>
|
||
<el-form-item label="${comment}" prop="addressAdmin">
|
||
<el-input v-model="form.addressAdmin" placeholder="请输入${comment}" />
|
||
</el-form-item>
|
||
<el-form-item label="${comment}" prop="logJson">
|
||
<el-input v-model="form.logJson" type="textarea" placeholder="请输入内容" />
|
||
</el-form-item>
|
||
<el-form-item label="${comment}" prop="logImages">
|
||
<image-upload v-model="form.logImages"/>
|
||
</el-form-item>
|
||
<el-form-item label="${comment}" prop="createdAt">
|
||
<el-date-picker clearable
|
||
v-model="form.createdAt"
|
||
type="date"
|
||
value-format="yyyy-MM-dd"
|
||
placeholder="请选择${comment}">
|
||
</el-date-picker>
|
||
</el-form-item>
|
||
<el-form-item label="${comment}" prop="updatedAt">
|
||
<el-date-picker clearable
|
||
v-model="form.updatedAt"
|
||
type="date"
|
||
value-format="yyyy-MM-dd"
|
||
placeholder="请选择${comment}">
|
||
</el-date-picker>
|
||
</el-form-item>
|
||
<el-form-item label="${comment}" prop="deletedAt">
|
||
<el-date-picker clearable
|
||
v-model="form.deletedAt"
|
||
type="date"
|
||
value-format="yyyy-MM-dd"
|
||
placeholder="请选择${comment}">
|
||
</el-date-picker>
|
||
</el-form-item>
|
||
</el-form>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||
<el-button @click="cancel">取 消</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
|
||
<!-- 通话记录弹窗 -->
|
||
<call-record
|
||
v-if="recordDialogVisible && currentRecordType === 'call'"
|
||
:visible.sync="recordDialogVisible"
|
||
:order-info="currentOrder"
|
||
/>
|
||
|
||
<!-- 录音文件弹窗 -->
|
||
<audio-record
|
||
v-if="recordDialogVisible && currentRecordType === 'audio'"
|
||
:visible.sync="recordDialogVisible"
|
||
:order-info="currentOrder"
|
||
/>
|
||
|
||
<!-- 接单记录弹窗 -->
|
||
<receive-record
|
||
v-if="recordDialogVisible && currentRecordType === 'receive'"
|
||
:visible.sync="recordDialogVisible"
|
||
:order-info="currentOrder"
|
||
/>
|
||
|
||
<!-- 通知记录弹窗 -->
|
||
<notify-record
|
||
v-if="recordDialogVisible && currentRecordType === 'notify'"
|
||
:visible.sync="recordDialogVisible"
|
||
:order-info="currentOrder"
|
||
/>
|
||
|
||
<!-- 评价弹窗 -->
|
||
<comment-record
|
||
v-if="commentDialogVisible"
|
||
:visible.sync="commentDialogVisible"
|
||
:order-info="currentOrder"
|
||
/>
|
||
|
||
<!-- 编辑信息弹窗 -->
|
||
<edit-info
|
||
v-if="editInfoVisible"
|
||
:visible.sync="editInfoVisible"
|
||
:title="editInfoTitle"
|
||
:label="editInfoLabel"
|
||
:value="editInfoValue"
|
||
:order-info="editInfoOrder"
|
||
@success="handleEditInfoSuccess"
|
||
/>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { listOrder, getOrder, delOrder, addOrder, updateOrder, getReceiveRecords, getCallRecords, getAudioRecords, getNotifyRecords } from "@/api/system/Order"
|
||
import CallRecord from './components/CallRecord'
|
||
import AudioRecord from './components/AudioRecord'
|
||
import ReceiveRecord from './components/ReceiveRecord'
|
||
import NotifyRecord from './components/NotifyRecord'
|
||
import CommentRecord from './components/CommentRecord'
|
||
import EditInfo from './components/EditInfo'
|
||
|
||
export default {
|
||
name: "Order",
|
||
components: {
|
||
CallRecord,
|
||
AudioRecord,
|
||
ReceiveRecord,
|
||
NotifyRecord,
|
||
CommentRecord,
|
||
EditInfo
|
||
},
|
||
dicts: ['order_status'],
|
||
data() {
|
||
return {
|
||
// 遮罩层
|
||
loading: true,
|
||
// 选中数组
|
||
ids: [],
|
||
// 非单个禁用
|
||
single: true,
|
||
// 非多个禁用
|
||
multiple: true,
|
||
// 显示搜索条件
|
||
showSearch: true,
|
||
// 总条数
|
||
total: 0,
|
||
// 服务订单表格数据
|
||
OrderList: [],
|
||
// 弹出层标题
|
||
title: "",
|
||
// 是否显示弹出层
|
||
open: false,
|
||
// 当前编辑的行
|
||
currentEditRow: null,
|
||
currentPhoneEditRow: null,
|
||
// 查询参数
|
||
queryParams: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
type: null,
|
||
mainOrderId: null,
|
||
orderId: null,
|
||
transactionId: null,
|
||
name: null,
|
||
phone: null,
|
||
mark: null,
|
||
},
|
||
// 表单参数
|
||
form: {},
|
||
// 表单校验
|
||
rules: {
|
||
type: [
|
||
{ required: true, message: "1:服务项目 2:商品不能为空", trigger: "change" }
|
||
],
|
||
orderId: [
|
||
{ required: true, message: "订单号不能为空", trigger: "blur" }
|
||
],
|
||
createType: [
|
||
{ required: true, message: "1:用户自主下单,2:后台下单不能为空", trigger: "change" }
|
||
],
|
||
productId: [
|
||
{ required: true, message: "商品不能为空", trigger: "blur" }
|
||
],
|
||
name: [
|
||
{ required: true, message: "姓名不能为空", trigger: "blur" }
|
||
],
|
||
phone: [
|
||
{ required: true, message: "电话不能为空", trigger: "blur" }
|
||
],
|
||
address: [
|
||
{ required: true, message: "地址不能为空", trigger: "blur" }
|
||
],
|
||
num: [
|
||
{ required: true, message: "数量不能为空", trigger: "blur" }
|
||
],
|
||
totalPrice: [
|
||
{ required: true, message: "总价不能为空", trigger: "blur" }
|
||
],
|
||
payPrice: [
|
||
{ required: true, message: "支付金额不能为空", trigger: "blur" }
|
||
],
|
||
status: [
|
||
{ required: true, message: "订单状态 1:待接单 2:待服务,3:服务中,4:已结束 5:已取消 6:师傅完成服务 7:未服务提前结束订单不能为空", trigger: "change" }
|
||
],
|
||
isPause: [
|
||
{ required: true, message: "1:开始服务 2:暂停服务不能为空", trigger: "blur" }
|
||
],
|
||
isComment: [
|
||
{ required: true, message: "1:已评价 0:未评价不能为空", trigger: "blur" }
|
||
],
|
||
isAccept: [
|
||
{ required: true, message: "1:已经接单不能为空", trigger: "blur" }
|
||
],
|
||
},
|
||
commentDialogVisible: false, // 评价详情对话框可见性
|
||
currentOrder: null, // 当前操作的订单
|
||
commentList: [], // 当前评价列表
|
||
commentLoading: false, // 评价加载状态
|
||
recordDialogVisible: false,
|
||
recordDialogTitle: '',
|
||
currentRecordType: '',
|
||
recordList: [],
|
||
recordLoading: false,
|
||
// 编辑信息弹窗
|
||
editInfoVisible: false,
|
||
editInfoTitle: '',
|
||
editInfoLabel: '',
|
||
editInfoValue: '',
|
||
editInfoOrder: null
|
||
}
|
||
},
|
||
created() {
|
||
this.getList()
|
||
},
|
||
methods: {
|
||
/** 查询服务订单列表 */
|
||
getList() {
|
||
this.loading = true
|
||
listOrder(this.queryParams).then(response => {
|
||
this.OrderList = response.rows.map(item => ({
|
||
...item,
|
||
id: item.id || item.orderId, // 确保每行都有唯一标识
|
||
thjl: item.thjl || 0, // 通话记录数
|
||
lywj: item.lywj || 0, // 录音文件数
|
||
jdjl: item.jdjl || 0, // 接单记录数
|
||
tzjl: item.tzjl || 0, // 通知记录数
|
||
fwpj: item.fwpj || 0 // 评价数
|
||
}))
|
||
this.total = response.total
|
||
this.loading = false
|
||
}).catch(() => {
|
||
this.loading = false
|
||
})
|
||
},
|
||
// 取消按钮
|
||
cancel() {
|
||
this.open = false
|
||
this.reset()
|
||
},
|
||
// 表单重置
|
||
reset() {
|
||
this.form = {
|
||
id: null,
|
||
type: null,
|
||
mainOrderId: null,
|
||
orderId: null,
|
||
transactionId: null,
|
||
createType: null,
|
||
createPhone: null,
|
||
uid: null,
|
||
productId: null,
|
||
name: null,
|
||
phone: null,
|
||
address: null,
|
||
makeTime: null,
|
||
makeHour: null,
|
||
num: null,
|
||
totalPrice: null,
|
||
goodPrice: null,
|
||
servicePrice: null,
|
||
payPrice: null,
|
||
couponId: null,
|
||
deduction: null,
|
||
payTime: null,
|
||
status: null,
|
||
isPause: null,
|
||
mark: null,
|
||
addressId: null,
|
||
sku: null,
|
||
workerId: null,
|
||
firstWorkerId: null,
|
||
receiveTime: null,
|
||
isComment: null,
|
||
receiveType: null,
|
||
isAccept: null,
|
||
middlePhone: null,
|
||
userPhone: null,
|
||
workerPhone: null,
|
||
addressEn: null,
|
||
uidAdmin: null,
|
||
addressAdmin: null,
|
||
logStatus: null,
|
||
logJson: null,
|
||
jsonStatus: null,
|
||
logImages: null,
|
||
createdAt: null,
|
||
updatedAt: null,
|
||
deletedAt: null
|
||
}
|
||
this.resetForm("form")
|
||
},
|
||
/** 搜索按钮操作 */
|
||
handleQuery() {
|
||
this.queryParams.pageNum = 1
|
||
this.getList()
|
||
},
|
||
/** 重置按钮操作 */
|
||
resetQuery() {
|
||
this.resetForm("queryForm")
|
||
this.handleQuery()
|
||
},
|
||
// 多选框选中数据
|
||
handleSelectionChange(selection) {
|
||
this.ids = selection.map(item => item.id)
|
||
this.single = selection.length!==1
|
||
this.multiple = !selection.length
|
||
},
|
||
/** 新增按钮操作 */
|
||
handleAdd() {
|
||
this.reset()
|
||
this.open = true
|
||
this.title = "添加服务订单"
|
||
},
|
||
/** 修改按钮操作 */
|
||
handleUpdate(row) {
|
||
this.reset()
|
||
const id = row.id || this.ids
|
||
getOrder(id).then(response => {
|
||
this.form = response.data
|
||
this.open = true
|
||
this.title = "修改服务订单"
|
||
})
|
||
},
|
||
/** 提交按钮 */
|
||
submitForm() {
|
||
this.$refs["form"].validate(valid => {
|
||
if (valid) {
|
||
if (this.form.id != null) {
|
||
updateOrder(this.form).then(response => {
|
||
this.$modal.msgSuccess("修改成功")
|
||
this.open = false
|
||
this.getList()
|
||
})
|
||
} else {
|
||
addOrder(this.form).then(response => {
|
||
this.$modal.msgSuccess("新增成功")
|
||
this.open = false
|
||
this.getList()
|
||
})
|
||
}
|
||
}
|
||
})
|
||
},
|
||
/** 删除按钮操作 */
|
||
handleDelete(row) {
|
||
const ids = row.id || this.ids
|
||
this.$modal.confirm('是否确认删除服务订单编号为"' + ids + '"的数据项?').then(function() {
|
||
return delOrder(ids)
|
||
}).then(() => {
|
||
this.getList()
|
||
this.$modal.msgSuccess("删除成功")
|
||
}).catch(() => {})
|
||
},
|
||
/** 导出按钮操作 */
|
||
handleExport() {
|
||
this.download('system/Order/export', {
|
||
...this.queryParams
|
||
}, `Order_${new Date().getTime()}.xlsx`)
|
||
},
|
||
/** 处理姓名修改弹窗 */
|
||
handleNameEdit(row) {
|
||
if (row) {
|
||
// 来自表格行点击 - 直接修改行数据
|
||
this.editInfoOrder = row
|
||
this.editInfoValue = row.name || ''
|
||
} else {
|
||
// 来自搜索框点击 - 修改查询条件
|
||
this.editInfoOrder = null
|
||
this.editInfoValue = this.queryParams.name || ''
|
||
}
|
||
this.editInfoTitle = '修改姓名'
|
||
this.editInfoLabel = '姓名'
|
||
this.editInfoVisible = true
|
||
},
|
||
/** 处理电话修改弹窗 */
|
||
handlePhoneEdit(row) {
|
||
if (row) {
|
||
// 来自表格行点击 - 直接修改行数据
|
||
this.editInfoOrder = row
|
||
this.editInfoValue = row.phone || ''
|
||
} else {
|
||
// 来自搜索框点击 - 修改查询条件
|
||
this.editInfoOrder = null
|
||
this.editInfoValue = this.queryParams.phone || ''
|
||
}
|
||
this.editInfoTitle = '修改电话'
|
||
this.editInfoLabel = '电话'
|
||
this.editInfoVisible = true
|
||
},
|
||
/** 处理编辑信息成功 */
|
||
handleEditInfoSuccess(value) {
|
||
if (this.editInfoOrder) {
|
||
// 修改表格行数据
|
||
this.editInfoOrder[this.editInfoLabel === '姓名' ? 'name' : 'phone'] = value
|
||
} else {
|
||
// 修改查询条件
|
||
this.queryParams[this.editInfoLabel === '姓名' ? 'name' : 'phone'] = value
|
||
this.handleQuery()
|
||
}
|
||
},
|
||
/** 显示记录详情 */
|
||
showRecordDetails(row, type) {
|
||
this.currentOrder = row
|
||
this.currentRecordType = type
|
||
this.recordDialogVisible = true
|
||
},
|
||
/** 显示评价详情 */
|
||
showCommentDetails(row) {
|
||
this.currentOrder = row
|
||
this.commentDialogVisible = true
|
||
},
|
||
/** 处理命令 */
|
||
handleCommand(command, row) {
|
||
if (command === 'jdjl') {
|
||
this.showRecordDetails(row, 'receive')
|
||
} else if (command === 'lywj') {
|
||
this.showRecordDetails(row, 'audio')
|
||
} else if (command === 'tzjl') {
|
||
this.showRecordDetails(row, 'notify')
|
||
}
|
||
},
|
||
statusTypeMap(status) {
|
||
const statusMap = {
|
||
'1': 'warning', // 待接单
|
||
'2': 'info', // 待服务
|
||
'3': 'primary', // 服务中
|
||
'4': 'success', // 已结束
|
||
'5': 'danger', // 已取消
|
||
'6': 'success', // 师傅完成服务
|
||
'7': 'danger' // 未服务提前结束订单
|
||
}
|
||
return statusMap[status] || 'info';
|
||
},
|
||
// 格式化时长
|
||
formatDuration(seconds) {
|
||
const minutes = Math.floor(seconds / 60);
|
||
const remainingSeconds = seconds % 60;
|
||
return `${minutes}分${remainingSeconds}秒`;
|
||
},
|
||
// 获取通知类型标签样式
|
||
getNotifyTypeTag(type) {
|
||
const typeMap = {
|
||
1: 'success',
|
||
2: 'warning',
|
||
3: 'info'
|
||
};
|
||
return typeMap[type] || 'info';
|
||
},
|
||
// 获取通知类型名称
|
||
getNotifyTypeName(type) {
|
||
const typeMap = {
|
||
1: '接单通知',
|
||
2: '服务通知',
|
||
3: '系统通知'
|
||
};
|
||
return typeMap[type] || '其他通知';
|
||
},
|
||
// 播放音频
|
||
playAudio(url) {
|
||
// 实现音频播放逻辑
|
||
},
|
||
// 下载音频
|
||
downloadAudio(url) {
|
||
// 实现音频下载逻辑
|
||
},
|
||
// 刷新记录
|
||
refreshRecords() {
|
||
if (this.currentOrder) {
|
||
this.getRecordList(this.currentOrder.orderId, this.currentRecordType);
|
||
}
|
||
},
|
||
// 处理弹窗关闭
|
||
handleRecordDialogClose() {
|
||
this.recordDialogVisible = false;
|
||
this.recordList = [];
|
||
},
|
||
// 解析 JSON 内容为对象数组
|
||
parseContentItems(content) {
|
||
if (!content) return [];
|
||
try {
|
||
const data = JSON.parse(content);
|
||
return Array.isArray(data) ? data : [data];
|
||
} catch (e) {
|
||
return [];
|
||
}
|
||
},
|
||
// 根据 item 对象解析 image 数组,用于 el-image 预览
|
||
getItemImageList(item) {
|
||
if (!item.image) return [];
|
||
try {
|
||
const imgs = item.image;
|
||
if (Array.isArray(imgs)) return imgs;
|
||
return imgs.toString().split(',').filter(u => u);
|
||
} catch (e) {
|
||
return [];
|
||
}
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.app-container {
|
||
padding: 20px;
|
||
background: #fff;
|
||
border-radius: 4px;
|
||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||
|
||
.search-box {
|
||
margin-bottom: 20px;
|
||
padding: 15px;
|
||
background: #f5f7fa;
|
||
border-radius: 4px;
|
||
}
|
||
}
|
||
|
||
.price-tag {
|
||
font-weight: bold;
|
||
color: #606266;
|
||
}
|
||
|
||
.pay-price-tag {
|
||
font-weight: bold;
|
||
color: #409EFF;
|
||
}
|
||
|
||
.discount-tag {
|
||
font-weight: bold;
|
||
color: #E6A23C;
|
||
}
|
||
|
||
.name-button:hover {
|
||
color: #409EFF;
|
||
text-decoration: underline;
|
||
}
|
||
|
||
.button-group {
|
||
display: flex;
|
||
justify-content: space-around;
|
||
align-items: center;
|
||
padding: 0 5px;
|
||
min-width: 150px;
|
||
}
|
||
|
||
.button-group .el-button {
|
||
padding: 6px;
|
||
margin: 0 3px;
|
||
border-radius: 50%;
|
||
width: 28px;
|
||
height: 28px;
|
||
line-height: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.button-group .el-button + .el-button {
|
||
margin-left: 5px;
|
||
}
|
||
|
||
.button-group .el-dropdown {
|
||
margin: 0 3px;
|
||
height: 28px;
|
||
line-height: 28px;
|
||
}
|
||
|
||
.button-group .el-dropdown .el-button {
|
||
margin: 0;
|
||
}
|
||
|
||
.small-padding.fixed-width {
|
||
padding: 8px 0;
|
||
}
|
||
|
||
.expand-button {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 0;
|
||
color: #606266;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.expand-button:hover {
|
||
color: #409EFF;
|
||
}
|
||
|
||
.comment-box {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
height: 100%;
|
||
}
|
||
|
||
.comment-count {
|
||
margin-right: 5px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.dialog-content {
|
||
min-height: 300px;
|
||
}
|
||
|
||
.dialog-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.order-info {
|
||
font-weight: bold;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.comment-content {
|
||
line-height: 1.6;
|
||
text-align: left;
|
||
padding: 5px 0;
|
||
}
|
||
|
||
.image-preview-container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: 5px;
|
||
max-height: 300px;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.image-preview-popover {
|
||
max-width: 150px;
|
||
max-height: 300px;
|
||
}
|
||
|
||
.empty-comment {
|
||
padding: 40px 0;
|
||
text-align: center;
|
||
color: #909399;
|
||
}
|
||
|
||
.empty-comment i {
|
||
font-size: 40px;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.record-box {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
height: 100%;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.record-box:hover .expand-button {
|
||
color: #409EFF;
|
||
}
|
||
|
||
.record-count {
|
||
margin-right: 5px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.empty-record {
|
||
padding: 40px 0;
|
||
text-align: center;
|
||
color: #909399;
|
||
}
|
||
|
||
.empty-record i {
|
||
font-size: 40px;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.code-content {
|
||
position: relative;
|
||
background: #f8f9fa;
|
||
border-radius: 4px;
|
||
padding: 8px 12px;
|
||
|
||
pre {
|
||
margin: 0;
|
||
white-space: pre-wrap;
|
||
word-wrap: break-word;
|
||
font-family: Consolas, Monaco, 'Courier New', monospace;
|
||
font-size: 12px;
|
||
line-height: 1.5;
|
||
max-height: 200px;
|
||
overflow-y: auto;
|
||
|
||
code {
|
||
::v-deep {
|
||
.keyword {
|
||
color: #d73a49;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.string {
|
||
color: #22863a;
|
||
}
|
||
|
||
.comment {
|
||
color: #6a737d;
|
||
font-style: italic;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.copy-btn {
|
||
position: absolute;
|
||
top: 4px;
|
||
right: 4px;
|
||
padding: 4px;
|
||
opacity: 0;
|
||
transition: opacity 0.2s;
|
||
|
||
i {
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
|
||
&:hover {
|
||
.copy-btn {
|
||
opacity: 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 滚动条样式
|
||
.code-content pre::-webkit-scrollbar {
|
||
width: 6px;
|
||
height: 6px;
|
||
}
|
||
|
||
.code-content pre::-webkit-scrollbar-thumb {
|
||
background: #ccc;
|
||
border-radius: 3px;
|
||
}
|
||
|
||
.code-content pre::-webkit-scrollbar-track {
|
||
background: #f8f9fa;
|
||
}
|
||
</style>
|