integralOrderDetails.vue 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. <template>
  2. <div style="background-color: #f0f2f5; padding-bottom: 20px; min-height: 100%; ">
  3. <div style="padding: 20px; background-color: #fff;">
  4. 积分订单详情
  5. </div>
  6. <div class="contentx" v-if="item != null">
  7. <div class="desct"> 积分订单信息</div>
  8. <div class="order-status" v-if="item != null && item.status != 5">
  9. <el-steps :active="getStepActive(item.status)" align-center finish-status="success">
  10. <el-step title="待支付"></el-step>
  11. <el-step title="待发货"></el-step>
  12. <el-step title="待收货"></el-step>
  13. <el-step title="已完成"></el-step>
  14. </el-steps>
  15. </div>
  16. <el-card shadow="never" style="margin-top: 15px">
  17. <div class="operate-container" v-if="item != null">
  18. <span style="margin-left: 20px" class="color-danger">订单状态:
  19. <el-tag prop="status" v-for="(ite, index) in statusOptions" v-if="item.status == ite.dictValue">{{
  20. ite.dictLabel }}</el-tag>
  21. </span>
  22. <div class="operate-button-container" v-if="item.status == 1" v-hasPermi="['his:integralOrder:sendGoods']">
  23. <!-- <el-button size="mini" @click="sendVisible=true" >发货</el-button> -->
  24. <el-button size="mini" @click="showSend()">发货</el-button>
  25. </div>
  26. <div class="operate-button-container" v-if="item.deliverySn != null"
  27. v-hasPermi="['his:integralOrder:express']">
  28. <el-button size="mini" @click="showExpress()">查看物流</el-button>
  29. </div>
  30. <div class="operate-button-container" v-if="item.status!=-1" v-hasPermi="['his:integralOrder:edit']">
  31. <el-button size="mini" @click="updateOrder()">修改订单</el-button>
  32. </div>
  33. <div class="operate-button-container" v-if="item.status==2">
  34. <el-button size="mini" @click="handleFinishOrder">确认收货</el-button>
  35. </div>
  36. <div class="operate-button-container" v-if="item.status>1" v-hasPermi="['his:integralOrder:cancel']">
  37. <el-button size="mini" @click="applyRefund">申请退款</el-button>
  38. </div>
  39. </div>
  40. <div class="desct">
  41. 基本信息
  42. </div>
  43. <el-descriptions title="" :column="3" border>
  44. <el-descriptions-item label="订单编号"><span v-if="item != null">{{ item.orderCode
  45. }}</span></el-descriptions-item>
  46. <el-descriptions-item label="会员ID"><span v-if="item != null">{{ item.userId }}</span></el-descriptions-item>
  47. <el-descriptions-item label="会员"><span v-if="item.nickName != null">{{ item.nickName }}({{ item.phone
  48. }})</span></el-descriptions-item>
  49. <el-descriptions-item label="用户名称"><span v-if="item != null">{{ item.userName }}</span></el-descriptions-item>
  50. <el-descriptions-item label="用户电话"><span v-if="item != null">{{ item.userPhone }}</span>
  51. <el-button icon="el-icon-search" size="mini" @click="handlePhone()" style="margin-left: 20px;" circle
  52. v-hasPermi="['his:integralOrder:queryPhone']"></el-button>
  53. </el-descriptions-item>
  54. <el-descriptions-item label="用户地址"><span v-if="item != null">{{ item.userAddress
  55. }}</span></el-descriptions-item>
  56. <el-descriptions-item label="支付积分"><span v-if="item != null">{{ item.integral }}</span></el-descriptions-item>
  57. <el-descriptions-item label="状态"><span v-if="item != null"> <dict-tag :options="statusOptions"
  58. :value="item.status" /></span></el-descriptions-item>
  59. <el-descriptions-item label="快递公司编号"><span v-if="item != null">{{ item.deliveryCode
  60. }}</span></el-descriptions-item>
  61. <el-descriptions-item label="快递名称"><span v-if="item != null">{{ item.deliveryName
  62. }}</span></el-descriptions-item>
  63. <el-descriptions-item label="快递单号"><span v-if="item != null">{{ item.deliverySn
  64. }}</span></el-descriptions-item>
  65. <!-- <el-descriptions-item label="物流状态"><span v-if="item != null">{{ item.deliveryType
  66. }}</span></el-descriptions-item> -->
  67. <el-descriptions-item label="物流状态" ><dict-tag :options="deliveryStatusOptions" :value="item.deliveryStatus"/></el-descriptions-item>
  68. <el-descriptions-item label="物流跟踪状态" ><span v-if="item!=null"><dict-tag :options="deliveryTypeOptions" :value="item.deliveryType"/> </span></el-descriptions-item>
  69. <el-descriptions-item label="发货时间"><span v-if="item != null">{{ item.deliveryTime
  70. }}</span></el-descriptions-item>
  71. <el-descriptions-item label="提交时间"><span v-if="item != null">{{ item.createTime
  72. }}</span></el-descriptions-item>
  73. </el-descriptions>
  74. </el-card>
  75. </div>
  76. <div class="contentx" v-if="item != null" style="padding-bottom: 70px;">
  77. <div class="desct">
  78. 商品信息
  79. </div>
  80. <el-table border v-if="prod != null" :data="prod" size="small" style="margin-top: 20px">
  81. <el-table-column label="商品图片" align="center">
  82. <template slot-scope="scope">
  83. <img :src="scope.row.imgUrl" style="height: 80px">
  84. </template>
  85. </el-table-column>
  86. <el-table-column label="商品名称" align="center">
  87. <template slot-scope="scope">
  88. <p>{{ scope.row.goodsName }}</p>
  89. </template>
  90. </el-table-column>
  91. <el-table-column label="积分" align="center">
  92. <template slot-scope="scope">
  93. <p>¥{{ scope.row.integral }}</p>
  94. </template>
  95. </el-table-column>
  96. <el-table-column label="金额" align="center">
  97. <template slot-scope="scope">
  98. <p>¥{{ scope.row.cash || 0 }}</p>
  99. </template>
  100. </el-table-column>
  101. </el-table>
  102. </div>
  103. <!-- 操作记录 -->
  104. <div class="contentx" v-if="item != null" style="padding-bottom: 70px;">
  105. <div class="desct">
  106. 操作记录
  107. </div>
  108. <el-table :data="orderLogs" border style="width: 100%; margin-top: 20px;" v-loading="logsLoading">
  109. <!-- <el-table-column prop="changeType" label="操作类型" align="center" width="120">
  110. </el-table-column> -->
  111. <el-table-column prop="changeTime" label="操作时间" align="center" width="180">
  112. <template slot-scope="scope">
  113. {{ parseTime(scope.row.changeTime) }}
  114. </template>
  115. </el-table-column>
  116. <el-table-column prop="changeMessage" label="操作备注" align="center">
  117. </el-table-column>
  118. <!-- <el-table-column prop="operator" label="操作员" align="center" width="120">
  119. </el-table-column> -->
  120. </el-table>
  121. </div>
  122. <el-dialog width="35%" title="发货" :visible.sync="sendVisible" append-to-body @close="sendCancel">
  123. <el-form ref="form" :model="form" label-width="120px">
  124. <el-form-item label="快递名称" prop="deliveryName">
  125. <el-select v-model="selectedExpress" placeholder="请选择快递名称" value-key="name">
  126. <el-option v-for="item in expressOption" :key="item.name" :label="item.name" :value="item">
  127. </el-option>
  128. </el-select>
  129. </el-form-item>
  130. <el-form-item label="快递公司编号" prop="deliveryCode">
  131. <el-input v-model="form.deliveryCode" placeholder="请输入快递公司编号" disabled />
  132. </el-form-item>
  133. <el-form-item label="快递单号" prop="deliverySn">
  134. <el-input v-model="form.deliverySn" placeholder="请输入快递单号" />
  135. </el-form-item>
  136. <!-- 代服账号选择表格 -->
  137. <!-- <el-form-item label="代服账号选择" prop="selectedAccount" required>
  138. <div style="border: 1px solid #e6ebf5; border-radius: 4px; padding: 10px;">
  139. <el-table ref="accountTable" :data="tableData" highlight-current-row
  140. @current-change="handleAccountSelectionChange" style="width: 100%" size="small" max-height="400">
  141. <el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
  142. <el-table-column prop="loginAccount" label="登录账号" align="center" width="120"
  143. show-overflow-tooltip></el-table-column>
  144. <el-table-column prop="monthlyCard" label="月结账号" align="center" width="120"
  145. show-overflow-tooltip></el-table-column>
  146. <el-table-column prop="expressProductCode" label="物流产品" align="center" width="120" show-overflow-tooltip>
  147. <template slot-scope="scope">
  148. <dict-tag :options="expressOptions" :value="scope.row.expressProductCode" />
  149. </template>
  150. </el-table-column>
  151. <el-table-column prop="senderName" label="寄件人姓名" align="center" width="100"></el-table-column>
  152. <el-table-column prop="senderPhone" label="寄件人手机" align="center" width="120"></el-table-column>
  153. <el-table-column prop="senderProvince" label="寄件人省" align="center" width="100"
  154. show-overflow-tooltip></el-table-column>
  155. <el-table-column prop="senderCity" label="寄件人市" align="center" width="100"
  156. show-overflow-tooltip></el-table-column>
  157. <el-table-column prop="senderDistrict" label="寄件人区" align="center" width="100"
  158. show-overflow-tooltip></el-table-column>
  159. <el-table-column prop="senderAddress" label="寄件人地址" align="center" min-width="150"
  160. show-overflow-tooltip></el-table-column>
  161. </el-table>
  162. <el-pagination small layout="prev, pager, next" :total="total" :page-size="queryParams.pageSize"
  163. :current-page="queryParams.pageNum" @current-change="handlePageChange"
  164. style="margin-top: 10px; text-align: center;">
  165. </el-pagination>
  166. <div style="margin-top: 10px; color: #909399; font-size: 12px; text-align: center;">
  167. 提示:点击表格行选择代服账号
  168. </div>
  169. <div v-if="selectedRow" style="margin-top: 10px; padding: 8px; background: #f5f7fa; border-radius: 4px;">
  170. <span style="color: #67C23A;">已选择:</span>
  171. <span>{{ selectedRow.loginAccount }} ({{ selectedRow.senderName }})</span>
  172. </div>
  173. </div>
  174. </el-form-item> -->
  175. </el-form>
  176. <div slot="footer" class="dialog-footer">
  177. <el-button type="primary" @click="sendGoods">确 定</el-button>
  178. <el-button @click="sendCancel">取 消</el-button>
  179. </div>
  180. </el-dialog>
  181. <el-dialog :title="expressDialog.title" :visible.sync="expressDialog.open" width="600px" append-to-body>
  182. <div style="margin-bottom: 10px; text-align: right;">
  183. <el-button type="primary" size="small" @click="syncExpressInfo" :loading="syncLoading">同步物流信息</el-button>
  184. </div>
  185. <el-table style="margin-top: 20px;width: 100%" ref="orderHistoryTable" :data="traces" border v-loading="tableLoading">
  186. <el-table-column label="操作时间" width="160" align="center">
  187. <template slot-scope="scope">
  188. {{ scope.row.AcceptTime }}
  189. </template>
  190. </el-table-column>
  191. <el-table-column label="位置" align="center">
  192. <template slot-scope="scope">
  193. {{ scope.row.Location }}
  194. </template>
  195. </el-table-column>
  196. <el-table-column label="描述" align="center">
  197. <template slot-scope="scope">
  198. {{ scope.row.AcceptStation }}
  199. </template>
  200. </el-table-column>
  201. </el-table>
  202. </el-dialog>
  203. <el-dialog :title="editOrder.title" :visible.sync="editOrder.open" width="600px" append-to-body>
  204. <el-form ref="editForm" :model="editForm" :rules="editRules" label-width="100px">
  205. <el-form-item label="订单状态" prop="status">
  206. <el-select v-model="editForm.status" placeholder="请选择状态" clearable size="small" filterable>
  207. <el-option v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictLabel"
  208. :value="dict.dictValue" :disabled="dict.dictValue==4||dict.dictValue==6||dict.dictValue==-1"/>
  209. </el-select>
  210. </el-form-item>
  211. <el-form-item label="收货地址" required v-if="item.status == 1">
  212. <div style="margin-bottom: 10px;">
  213. <el-select
  214. v-model="selectedProvince"
  215. placeholder="请选择省"
  216. style="width: 32%; margin-right: 1%"
  217. @change="onProvinceChange"
  218. clearable
  219. >
  220. <el-option
  221. v-for="item in provinceOptions"
  222. :key="item.value"
  223. :label="item.label"
  224. :value="item"
  225. />
  226. </el-select>
  227. <el-select
  228. v-model="selectedCity"
  229. placeholder="请选择市"
  230. style="width: 32%; margin-right: 1%"
  231. @change="onCityChange"
  232. :disabled="!selectedProvince"
  233. clearable
  234. >
  235. <el-option
  236. v-for="item in cityOptions"
  237. :key="item.value"
  238. :label="item.label"
  239. :value="item"
  240. />
  241. </el-select>
  242. <el-select
  243. v-model="selectedDistrict"
  244. placeholder="请选择区"
  245. style="width: 32%;"
  246. @change="onDistrictChange"
  247. :disabled="!selectedCity"
  248. clearable
  249. >
  250. <el-option
  251. v-for="item in districtOptions"
  252. :key="item.value"
  253. :label="item.label"
  254. :value="item"
  255. />
  256. </el-select>
  257. </div>
  258. <el-input
  259. v-model="detailAddress"
  260. placeholder="请输入详细地址(街道、门牌号等)"
  261. style="width: 100%"
  262. clearable
  263. />
  264. </el-form-item>
  265. <!-- 其他状态显示只读的地址信息 -->
  266. <el-form-item label="收货地址" v-else>
  267. <el-input
  268. v-model="editForm.userAddress"
  269. placeholder="请输入"
  270. disabled
  271. />
  272. </el-form-item>
  273. <!-- 修改:快递信息改为下拉选择 -->
  274. <el-form-item label="快递名称" prop="deliveryName">
  275. <el-select v-model="editSelectedExpress" placeholder="请选择快递名称" value-key="name" clearable>
  276. <el-option v-for="item in expressOption" :key="item.name" :label="item.name" :value="item">
  277. </el-option>
  278. </el-select>
  279. </el-form-item>
  280. <el-form-item label="快递公司编号" prop="deliveryCode">
  281. <el-input v-model="editForm.deliveryCode" placeholder="快递公司编号" disabled />
  282. </el-form-item>
  283. <el-form-item label="快递单号" prop="deliverySn">
  284. <el-input v-model="editForm.deliverySn" placeholder="请输入快递单号" />
  285. </el-form-item>
  286. <!-- 代服账号选择表格 - 使用同一个数据源 -->
  287. <!-- <el-form-item label="代服账号" prop="loginAccount">
  288. <div style="border: 1px solid #e6ebf5; border-radius: 4px; padding: 10px;">
  289. <el-table ref="editAccountTable" :data="tableData" highlight-current-row
  290. @current-change="handleEditAccountSelectionChange" style="width: 100%" size="small" max-height="300">
  291. <el-table-column type="index" width="60" label="序号" align="center"></el-table-column>
  292. <el-table-column prop="loginAccount" label="登录账号" align="center" width="120"
  293. show-overflow-tooltip></el-table-column>
  294. <el-table-column prop="monthlyCard" label="月结账号" align="center" width="120"
  295. show-overflow-tooltip></el-table-column>
  296. <el-table-column prop="expressProductCode" label="物流产品" align="center" width="120" show-overflow-tooltip>
  297. <template slot-scope="scope">
  298. <dict-tag :options="expressOptions" :value="scope.row.expressProductCode" />
  299. </template>
  300. </el-table-column>
  301. <el-table-column prop="senderName" label="寄件人姓名" align="center" width="100"></el-table-column>
  302. <el-table-column prop="senderPhone" label="寄件人手机" align="center" width="120"></el-table-column>
  303. <el-table-column prop="senderProvince" label="寄件人省" align="center" width="100"
  304. show-overflow-tooltip></el-table-column>
  305. <el-table-column prop="senderCity" label="寄件人市" align="center" width="100"
  306. show-overflow-tooltip></el-table-column>
  307. <el-table-column prop="senderDistrict" label="寄件人区" align="center" width="100"
  308. show-overflow-tooltip></el-table-column>
  309. <el-table-column prop="senderAddress" label="寄件人地址" align="center" min-width="150"
  310. show-overflow-tooltip></el-table-column>
  311. </el-table>
  312. <el-pagination small layout="prev, pager, next" :total="total" :page-size="queryParams.pageSize"
  313. :current-page="queryParams.pageNum" @current-change="handlePageChange"
  314. style="margin-top: 10px; text-align: center;">
  315. </el-pagination>
  316. <div style="margin-top: 10px; color: #909399; font-size: 12px; text-align: center;">
  317. 提示:点击表格行选择代服账号
  318. </div>
  319. <div v-if="editSelectedRow"
  320. style="margin-top: 10px; padding: 8px; background: #f5f7fa; border-radius: 4px;">
  321. <span style="color: #67C23A;">已选择:</span>
  322. <span>{{ editSelectedRow.loginAccount }} ({{ editSelectedRow.senderName }})</span>
  323. </div>
  324. </div>
  325. </el-form-item> -->
  326. <el-form-item label="备注" prop="remark">
  327. <el-input v-model="editForm.remark" placeholder="请输入备注" />
  328. </el-form-item>
  329. </el-form>
  330. <div slot="footer" class="dialog-footer">
  331. <el-button type="primary" @click="submitEditForm">确 定</el-button>
  332. </div>
  333. </el-dialog>
  334. </div>
  335. </template>
  336. <script>
  337. import { getExpress,mandatoryRefunds,getCitys,finishOrder, listIntegralOrder, sendgoods, getIntegralOrder, delIntegralOrder, addIntegralOrder, updateIntegralOrder, exportIntegralOrder, getOrderUserPhone, getOrderLogs } from "@/api/his/integralOrder";
  338. import { getExpressList } from "@/api/his/express";
  339. import { listAccount } from "@/api/his/dfAccount";
  340. export default {
  341. name: "integralOrder",
  342. data() {
  343. return {
  344. deliveryStatusOptions:[],
  345. selectedExpress: null,
  346. expressOption: [],
  347. expressDialog: {
  348. title: "物流信息",
  349. open: false,
  350. },
  351. editOrder: {
  352. title: "修改订单",
  353. open: false,
  354. },
  355. editForm: {
  356. orderId: null,
  357. status: null,
  358. userAddress: null, // 这个字段将存储拼接后的完整地址
  359. remark: "",
  360. loginAccount: null,
  361. // 新增快递相关字段
  362. deliveryName: null,
  363. deliveryCode: null,
  364. deliverySn: null
  365. },
  366. editRules: {
  367. deliveryName: [
  368. { required: false, message: '请输入快递名称', trigger: 'blur' }
  369. ],
  370. deliveryCode: [
  371. { required: false, message: '请输入快递公司编号', trigger: 'blur' }
  372. ],
  373. deliverySn: [
  374. { required: false, message: '请输入快递单号', trigger: 'blur' }
  375. ]
  376. },
  377. item: null,
  378. express: null,
  379. traces: [],
  380. rules: {
  381. deliveryCode: [
  382. { required: true, message: '请输入快递公司编号', trigger: 'blur' }
  383. ],
  384. deliveryName: [
  385. { required: true, message: '请输入快递名称', trigger: 'blur' }
  386. ],
  387. deliverySn: [
  388. { required: true, message: '请输入快递单号', trigger: 'blur' }
  389. ],
  390. selectedAccount: [ // 添加这一项
  391. { required: true, message: '请选择代服账号', trigger: 'change' }
  392. ]
  393. },
  394. sendVisible: false,
  395. form: {
  396. deliveryCode: null,
  397. deliveryName: null,
  398. deliverySn: null,
  399. orderId: null,
  400. loginAccount: null // 在 form 中也添加这个字段
  401. },
  402. tableData: [], // 清空模拟数据,改为空数组
  403. selectedRow: null,
  404. editSelectedRow: null, // 修改订单弹窗选中的行
  405. queryParams: { // 查询参数
  406. pageNum: 1,
  407. pageSize: 10
  408. },
  409. total: 0, // 总条数,
  410. expressOptions: [], // 物流产品字典
  411. editSelectedExpress: null,
  412. // 地址选择相关数据
  413. provinceOptions: [], // 省列表
  414. cityOptions: [], // 市列表
  415. districtOptions: [], // 区列表
  416. selectedProvince: null, // 选中的省
  417. selectedCity: null, // 选中的市
  418. selectedDistrict: null, // 选中的区
  419. detailAddress: '', // 详细地址
  420. deliveryTypeOptions:[],
  421. // 操作记录相关数据
  422. orderLogs: [], // 订单操作记录
  423. logsLoading: false, // 操作记录加载状态
  424. syncLoading: false, // 同步物流信息按钮加载状态
  425. tableLoading: false // 物流信息表格加载状态
  426. }
  427. },
  428. created() {
  429. this.getDicts("sys_integral_order_status").then(response => {
  430. this.statusOptions = response.data;
  431. });
  432. this.getDicts("df_account_express").then(response => {
  433. this.expressOptions = response.data;
  434. });
  435. this.getDicts("sys_store_order_delivery_status").then(response => {
  436. this.deliveryStatusOptions = response.data;
  437. });
  438. this.getDicts("sys_delivery_type").then(response => {
  439. this.deliveryTypeOptions = response.data;
  440. });
  441. },
  442. watch: {
  443. selectedExpress(newVal) {
  444. console.log('选中的快递:', newVal); // 调试用
  445. if (newVal && newVal.name && newVal.code) {
  446. this.form.deliveryName = newVal.name;
  447. this.form.deliveryCode = newVal.code;
  448. } else {
  449. this.form.deliveryName = '';
  450. this.form.deliveryCode = '';
  451. }
  452. },
  453. // 新增:修改订单弹窗的快递选择监听
  454. editSelectedExpress(newVal) {
  455. console.log('修改订单弹窗选中的快递:', newVal);
  456. if (newVal && newVal.name && newVal.code) {
  457. this.editForm.deliveryName = newVal.name;
  458. this.editForm.deliveryCode = newVal.code;
  459. } else {
  460. this.editForm.deliveryName = '';
  461. this.editForm.deliveryCode = '';
  462. }
  463. },
  464. 'editOrder.open': function (newVal) {
  465. if (!newVal) {
  466. // 修改订单弹窗关闭时清理选择状态
  467. this.editSelectedRow = null;
  468. if (this.$refs.editAccountTable) {
  469. this.$refs.editAccountTable.setCurrentRow();
  470. }
  471. }
  472. },
  473. 'expressDialog.open': function (newVal) {
  474. if (!newVal) {
  475. // 查看物流弹窗关闭时清理数据
  476. this.express = null;
  477. this.traces = [];
  478. }
  479. },
  480. },
  481. methods: {
  482. getStepActive(status) {
  483. const statusMap = {
  484. 4: 1, // 待支付 -> 激活第1步(显示到待支付)
  485. 1: 2, // 待发货 -> 激活第2步(显示到待发货)
  486. 2: 3, // 待收货 -> 激活第3步(显示到待收货)
  487. 3: 4 // 已完成 -> 激活第4步(全部完成)
  488. };
  489. return statusMap[status] || 0;
  490. },
  491. handlePhone() {
  492. const orderId = this.item.orderId;
  493. getOrderUserPhone(orderId).then(response => {
  494. this.item.userPhone = response.userPhone;
  495. })
  496. },
  497. async updateOrder() {
  498. this.editOrder.open = true;
  499. this.editForm.orderId = this.item.orderId;
  500. this.editForm.remark = this.item.remark;
  501. this.editForm.status = this.item.status.toString();
  502. this.editForm.userAddress = this.item.userAddress.toString();
  503. this.editForm.loginAccount = this.item.loginAccount;
  504. // 设置快递字段的初始值
  505. this.editForm.deliveryName = this.item.deliveryName;
  506. this.editForm.deliveryCode = this.item.deliveryCode;
  507. this.editForm.deliverySn = this.item.deliverySn;
  508. // 重置选择状态
  509. this.editSelectedRow = null;
  510. this.editSelectedExpress = null;
  511. try {
  512. // 1. 先确保快递选项数据已加载
  513. if (this.expressOption.length === 0) {
  514. await getExpressList().then(response => {
  515. this.expressOption = response.data;
  516. });
  517. }
  518. // 2. 设置选中的快递(在快递数据加载完成后)
  519. if (this.item.deliveryName && this.expressOption.length > 0) {
  520. const currentExpress = this.expressOption.find(item =>
  521. item.name === this.item.deliveryName
  522. );
  523. if (currentExpress) {
  524. this.editSelectedExpress = currentExpress;
  525. }
  526. }
  527. // 3. 初始化地址选择器(只在待发货状态时执行)
  528. if (this.item.status == 1) {
  529. await this.initAddressSelector();
  530. }
  531. // 4. 等待代服账号数据加载完成
  532. await this.getAccountList();
  533. // 5. 在数据都加载完成后尝试选中对应的行
  534. if (this.item.loginAccount) {
  535. this.$nextTick(() => {
  536. this.selectCurrentAccount();
  537. });
  538. }
  539. } catch (error) {
  540. console.error('加载数据失败:', error);
  541. }
  542. },
  543. // 初始化地址选择器
  544. async initAddressSelector() {
  545. // 重置地址选择器
  546. this.provinceOptions = [];
  547. this.cityOptions = [];
  548. this.districtOptions = [];
  549. this.selectedProvince = null;
  550. this.selectedCity = null;
  551. this.selectedDistrict = null;
  552. this.detailAddress = '';
  553. // 只有在待发货状态时才初始化地址选择器
  554. if (this.item.status == 1) {
  555. // 获取省份数据
  556. try {
  557. const response = await getCitys(); // 假设getCitys是您导入的方法
  558. this.provinceOptions = response.data || [];
  559. // 如果现有地址不为空,尝试解析并设置初始值
  560. if (this.item.userAddress) {
  561. this.parseExistingAddress(this.item.userAddress);
  562. }
  563. } catch (error) {
  564. console.error('获取地址数据失败:', error);
  565. }
  566. }
  567. },
  568. // 解析现有地址
  569. parseExistingAddress(address) {
  570. if (!address || this.item.status != 1) return;
  571. // 假设地址格式为 "省 市 区 详细地址"
  572. const parts = address.split(' ');
  573. if (parts.length >= 4) {
  574. const provinceName = parts[0];
  575. const cityName = parts[1];
  576. const districtName = parts[2];
  577. this.detailAddress = parts.slice(3).join(' '); // 剩余部分作为详细地址
  578. // 设置省份
  579. const province = this.provinceOptions.find(p => p.label === provinceName);
  580. if (province) {
  581. this.selectedProvince = province;
  582. this.onProvinceChange(province);
  583. // 设置城市
  584. const city = province.children?.find(c => c.label === cityName);
  585. if (city) {
  586. this.selectedCity = city;
  587. this.onCityChange(city);
  588. // 设置区域
  589. const district = city.children?.find(d => d.label === districtName);
  590. if (district) {
  591. this.selectedDistrict = district;
  592. }
  593. }
  594. }
  595. } else {
  596. // 如果格式不匹配,将整个地址作为详细地址
  597. this.detailAddress = address;
  598. }
  599. },
  600. // 省份选择变化
  601. onProvinceChange(province) {
  602. this.selectedCity = null;
  603. this.selectedDistrict = null;
  604. this.cityOptions = province?.children || [];
  605. this.districtOptions = [];
  606. },
  607. // 城市选择变化
  608. onCityChange(city) {
  609. this.selectedDistrict = null;
  610. this.districtOptions = city?.children || [];
  611. },
  612. // 区域选择变化
  613. onDistrictChange(district) {
  614. // 可以在这里处理区域选择后的逻辑
  615. },
  616. // 选中当前账号(修改订单弹窗使用)
  617. selectCurrentAccount() {
  618. if (!this.item.loginAccount || !this.tableData || this.tableData.length === 0) {
  619. console.log('无法选中账号:数据未就绪');
  620. return;
  621. }
  622. const currentAccount = this.tableData.find(item =>
  623. item.loginAccount === this.item.loginAccount
  624. );
  625. if (currentAccount) {
  626. this.editSelectedRow = currentAccount;
  627. this.$nextTick(() => {
  628. if (this.$refs.editAccountTable) {
  629. this.$refs.editAccountTable.setCurrentRow(currentAccount);
  630. console.log('成功选中代服账号:', currentAccount.loginAccount);
  631. }
  632. });
  633. } else {
  634. console.log('未找到对应的代服账号:', this.item.loginAccount);
  635. }
  636. },
  637. //修改订单状态
  638. submitEditForm() {
  639. // 只有在待发货状态(status=1)时才更新地址
  640. if (this.item.status == 1) {
  641. // 拼接完整地址
  642. const province = this.selectedProvince ? this.selectedProvince.label : '';
  643. const city = this.selectedCity ? this.selectedCity.label : '';
  644. const district = this.selectedDistrict ? this.selectedDistrict.label : '';
  645. const detail = this.detailAddress || '';
  646. // 使用空格拼接四个字段
  647. this.editForm.userAddress = `${province} ${city} ${district} ${detail}`.trim();
  648. } else {
  649. // 其他状态保持原地址不变
  650. this.editForm.userAddress = this.item.userAddress;
  651. }
  652. this.$refs["editForm"].validate(valid => {
  653. if (valid) {
  654. updateIntegralOrder(this.editForm).then(response => {
  655. if (response.code === 200) {
  656. this.msgSuccess("操作成功");
  657. this.editOrder.open = false;
  658. this.getDetails(this.item.orderId);
  659. }
  660. });
  661. }
  662. });
  663. },
  664. sendCancel() {
  665. this.sendVisible = false;
  666. this.form = {
  667. deliveryCode: null,
  668. deliveryName: null,
  669. deliverySn: null,
  670. orderId: null,
  671. loginAccount: null
  672. };
  673. this.selectedExpress = null;
  674. this.selectedRow = null;
  675. if (this.$refs.accountTable) {
  676. this.$refs.accountTable.setCurrentRow();
  677. }
  678. },
  679. showSend() {
  680. // 重置表单和选择状态
  681. this.form = {
  682. deliveryCode: null,
  683. deliveryName: null,
  684. deliverySn: null,
  685. orderId: null,
  686. loginAccount: null
  687. };
  688. this.selectedExpress = null;
  689. this.selectedRow = null;
  690. // 获取快递公司信息
  691. getExpressList().then(response => {
  692. this.expressOption = response.data;
  693. });
  694. // 获取代服账号列表
  695. this.getAccountList();
  696. this.sendVisible = true;
  697. },
  698. showExpress() {
  699. this.expressDialog.open = true;
  700. this.loadExpressInfo();
  701. },
  702. // 加载物流信息
  703. loadExpressInfo() {
  704. this.tableLoading = true;
  705. getExpress(this.item.orderId).then(response => {
  706. this.express = response.data;
  707. if (this.express != null && this.express.Traces != null) {
  708. this.traces = this.express.Traces
  709. } else {
  710. this.traces = [];
  711. }
  712. this.tableLoading = false;
  713. }).catch(error => {
  714. this.traces = [];
  715. this.tableLoading = false;
  716. console.error('获取物流信息失败:', error);
  717. });
  718. },
  719. // 同步物流信息
  720. syncExpressInfo() {
  721. this.syncLoading = true;
  722. this.loadExpressInfo();
  723. this.syncLoading = false;
  724. },
  725. sendGoods() {
  726. // 手动验证所有必填字段
  727. if (!this.selectedRow) {
  728. this.msgError('请选择代服账号');
  729. return;
  730. }
  731. if (!this.form.deliveryName || !this.form.deliveryCode) {
  732. this.msgError('请选择快递公司');
  733. return;
  734. }
  735. if (!this.form.deliverySn) {
  736. this.msgError('请输入快递单号');
  737. return;
  738. }
  739. // 所有验证通过,直接发送
  740. this.form.orderId = this.item.orderId;
  741. sendgoods(this.form).then(response => {
  742. this.msgSuccess("发货成功");
  743. this.sendVisible = false;
  744. getIntegralOrder(this.item.orderId).then(response => {
  745. this.item = response.data;
  746. this.$parent.$parent.getList();
  747. });
  748. this.form = {
  749. deliveryCode: null,
  750. deliveryName: null,
  751. deliverySn: null,
  752. orderId: null,
  753. loginAccount: null
  754. };
  755. this.selectedRow = null;
  756. });
  757. },
  758. getDetails(orderId) {
  759. this.item = null;
  760. this.orderLogs = []; // 清空操作记录
  761. getIntegralOrder(orderId).then(response => {
  762. this.item = response.data;
  763. this.prod = [JSON.parse(this.item.itemJson)][0];
  764. // 获取操作记录
  765. this.getOrderLogsData();
  766. });
  767. },
  768. // 代服账号选择变化
  769. handleAccountSelectionChange(currentRow, oldRow) {
  770. this.selectedRow = currentRow;
  771. if (currentRow) {
  772. this.form.loginAccount = currentRow.loginAccount;
  773. }
  774. },
  775. // 修改订单弹窗的代服账号选择
  776. handleEditAccountSelectionChange(currentRow, oldRow) {
  777. this.editSelectedRow = currentRow;
  778. if (currentRow) {
  779. this.editForm.loginAccount = currentRow.loginAccount;
  780. }
  781. },
  782. // 获取代服账号列表
  783. getAccountList() {
  784. return new Promise((resolve, reject) => {
  785. listAccount(this.queryParams).then(response => {
  786. this.tableData = response.rows || response.data || [];
  787. this.total = response.total || 0;
  788. resolve(this.tableData); // 数据加载完成
  789. }).catch(error => {
  790. this.tableData = [];
  791. reject(error);
  792. });
  793. });
  794. },
  795. handlePageChange(page) {
  796. this.queryParams.pageNum = page;
  797. this.getAccountList();
  798. },
  799. // 取消订单
  800. applyRefund() {
  801. this.$confirm('确定要取消该订单吗?取消后订单将无法恢复。', '取消订单确认', {
  802. confirmButtonText: '确定取消',
  803. cancelButtonText: '再想想',
  804. type: 'warning',
  805. confirmButtonClass: 'el-button--danger'
  806. }).then(() => {
  807. this.cancelOrder();
  808. }).catch(() => {
  809. this.$message({
  810. type: 'info',
  811. message: '已取消操作'
  812. });
  813. });
  814. },
  815. // 执行取消订单请求
  816. cancelOrder() {
  817. const orderCode = this.item.orderCode;
  818. mandatoryRefunds(orderCode).then(response => {
  819. if (response.code === 200) {
  820. this.msgSuccess("取消订单成功");
  821. // 刷新订单详情
  822. this.getDetails(this.item.orderId);
  823. // 刷新父组件列表(如果有)
  824. if (this.$parent && this.$parent.$parent && this.$parent.$parent.getList) {
  825. this.$parent.$parent.getList();
  826. }
  827. } else {
  828. this.msgError(response.msg || "取消订单失败");
  829. }
  830. }).catch(error => {
  831. this.msgError("取消订单失败");
  832. console.error('取消订单失败:', error);
  833. });
  834. },
  835. // 完成订单
  836. handleFinishOrder() {
  837. this.$confirm('确定要完成该订单吗?完成后订单状态将变为已完成。', '完成订单确认', {
  838. confirmButtonText: '确定完成',
  839. cancelButtonText: '取消',
  840. type: 'warning'
  841. }).then(() => {
  842. // 用户点击确定
  843. this.executeFinishOrder();
  844. }).catch(() => {
  845. // 用户点击取消
  846. this.$message({
  847. type: 'info',
  848. message: '已取消操作'
  849. });
  850. });
  851. },
  852. // 执行完成订单请求
  853. executeFinishOrder() {
  854. const orderCode = this.item.orderCode;
  855. console.log("请问请问",orderCode)
  856. finishOrder(orderCode).then(response => {
  857. if (response.code === 200) {
  858. this.msgSuccess("订单完成成功");
  859. // 刷新订单详情
  860. this.getDetails(this.item.orderId);
  861. // 刷新父组件列表(如果有)
  862. if (this.$parent && this.$parent.$parent && this.$parent.$parent.getList) {
  863. this.$parent.$parent.getList();
  864. }
  865. } else {
  866. this.msgError(response.msg || "订单完成失败");
  867. }
  868. }).catch(error => {
  869. this.msgError("订单完成失败");
  870. console.error('完成订单失败:', error);
  871. });
  872. },
  873. // 获取订单操作记录
  874. getOrderLogsData() {
  875. if (!this.item || !this.item.orderId) {
  876. return;
  877. }
  878. this.logsLoading = true;
  879. getOrderLogs(this.item.orderId).then(response => {
  880. if (response.code === 200) {
  881. // 按照时间升序排列
  882. this.orderLogs = response.data.sort((a, b) => {
  883. return new Date(a.changeTime) - new Date(b.changeTime);
  884. });
  885. } else {
  886. this.orderLogs = [];
  887. }
  888. this.logsLoading = false;
  889. }).catch(error => {
  890. this.orderLogs = [];
  891. this.logsLoading = false;
  892. console.error('获取操作记录失败:', error);
  893. });
  894. }
  895. }
  896. }
  897. </script>
  898. <style>
  899. .contentx {
  900. height: 100%;
  901. background-color: #fff;
  902. padding: 0px 20px 20px;
  903. margin: 20px;
  904. }
  905. .el-descriptions-item__label.is-bordered-label {
  906. font-weight: normal;
  907. }
  908. .el-descriptions-item__content {
  909. max-width: 150px;
  910. min-width: 100px;
  911. }
  912. .desct {
  913. padding-top: 20px;
  914. padding-bottom: 20px;
  915. color: #524b4a;
  916. font-weight: bold;
  917. }
  918. .operate-container {
  919. background: #F2F6FC;
  920. height: 60px;
  921. margin: -20px -20px 0;
  922. line-height: 60px;
  923. }
  924. .order-content {
  925. margin: 10px;
  926. }
  927. .operate-button-container {
  928. float: right;
  929. margin-right: 20px
  930. }
  931. </style>