index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. <template>
  2. <div class="app-container">
  3. <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="80px">
  4. <el-form-item label="订单编号" prop="orderCode">
  5. <el-input
  6. v-model="queryParams.orderCode"
  7. placeholder="请输入订单编号"
  8. clearable
  9. size="small"
  10. @keyup.enter.native="handleQuery"
  11. />
  12. </el-form-item>
  13. <el-form-item label="用户昵称" prop="nickName">
  14. <el-input
  15. v-model="queryParams.nickName"
  16. placeholder="请输入用户昵称"
  17. clearable
  18. size="small"
  19. @keyup.enter.native="handleQuery"
  20. />
  21. </el-form-item>
  22. <el-form-item label="所属公司" prop="companyId">
  23. <el-select v-model="queryParams.companyId" placeholder="请选择公司" clearable filterable size="small">
  24. <el-option
  25. v-for="item in companyList"
  26. :key="item.companyId"
  27. :label="item.companyName"
  28. :value="item.companyId"
  29. />
  30. </el-select>
  31. </el-form-item>
  32. <el-form-item label="服务类型" prop="serviceType">
  33. <el-select v-model="queryParams.serviceType" placeholder="请选择服务类型" clearable size="small">
  34. <el-option
  35. v-for="item in serviceTypeOptions"
  36. :key="item.dictValue"
  37. :label="item.dictLabel"
  38. :value="item.dictValue"
  39. />
  40. </el-select>
  41. </el-form-item>
  42. <el-form-item label="审核状态" prop="status">
  43. <el-select v-model="queryParams.status" placeholder="请选择审核状态" clearable size="small">
  44. <el-option
  45. v-for="item in statusOptions"
  46. :key="item.dictValue"
  47. :label="item.dictLabel"
  48. :value="item.dictValue"
  49. />
  50. </el-select>
  51. </el-form-item>
  52. <el-form-item label="售后状态" prop="salesStatus">
  53. <el-select v-model="queryParams.salesStatus" placeholder="请选择售后状态" clearable size="small">
  54. <el-option
  55. v-for="item in salesStatusOptions"
  56. :key="item.dictValue"
  57. :label="item.dictLabel"
  58. :value="item.dictValue"
  59. />
  60. </el-select>
  61. </el-form-item>
  62. <el-form-item label="物流单号" prop="deliverySn">
  63. <el-input
  64. v-model="queryParams.deliverySn"
  65. placeholder="请输入物流单号"
  66. clearable
  67. size="small"
  68. @keyup.enter.native="handleQuery"
  69. />
  70. </el-form-item>
  71. <el-form-item label="提交时间" prop="createTime">
  72. <el-date-picker
  73. v-model="dateRange"
  74. size="small"
  75. style="width: 220px"
  76. value-format="yyyy-MM-dd"
  77. type="daterange"
  78. range-separator="-"
  79. start-placeholder="开始日期"
  80. end-placeholder="结束日期"
  81. />
  82. </el-form-item>
  83. <el-form-item>
  84. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  85. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  86. </el-form-item>
  87. </el-form>
  88. <el-row :gutter="10" class="mb8">
  89. <el-col :span="1.5">
  90. <el-button
  91. type="warning"
  92. plain
  93. icon="el-icon-download"
  94. size="mini"
  95. :loading="exportLoading"
  96. @click="handleExport"
  97. v-hasPermi="['his:integralAfterSales:export']"
  98. >导出</el-button>
  99. </el-col>
  100. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  101. </el-row>
  102. <el-table v-loading="loading" border :data="afterSalesList" @selection-change="handleSelectionChange">
  103. <el-table-column type="selection" width="55" align="center" />
  104. <el-table-column label="售后单号" align="center" prop="id" width="90" />
  105. <el-table-column label="订单编号" align="center" prop="orderCode" show-overflow-tooltip />
  106. <el-table-column label="用户昵称" align="center" prop="nickName" />
  107. <el-table-column label="用户电话" align="center" prop="userPhone" />
  108. <el-table-column label="所属公司" align="center" prop="companyName" show-overflow-tooltip />
  109. <el-table-column label="退款金额" align="center" prop="refundAmount">
  110. <template slot-scope="scope">
  111. <span v-if="scope.row.refundAmount != null">¥{{ scope.row.refundAmount }}</span>
  112. <span v-else>-</span>
  113. </template>
  114. </el-table-column>
  115. <el-table-column label="退回积分" align="center" prop="refundIntegral">
  116. <template slot-scope="scope">
  117. <span v-if="scope.row.refundIntegral != null">{{ scope.row.refundIntegral }}</span>
  118. <span v-else>-</span>
  119. </template>
  120. </el-table-column>
  121. <el-table-column label="服务类型" align="center" prop="serviceType" width="100">
  122. <template slot-scope="scope">
  123. <el-tag v-if="getDictLabel(serviceTypeOptions, scope.row.serviceType)"
  124. :type="serviceTypeTagType(scope.row.serviceType)">
  125. {{ getDictLabel(serviceTypeOptions, scope.row.serviceType) }}
  126. </el-tag>
  127. <span v-else>-</span>
  128. </template>
  129. </el-table-column>
  130. <el-table-column label="审核状态" align="center" prop="status" width="100">
  131. <template slot-scope="scope">
  132. <el-tag v-if="getDictLabel(statusOptions, scope.row.status)"
  133. :type="statusTagType(scope.row.status)">
  134. {{ getDictLabel(statusOptions, scope.row.status) }}
  135. </el-tag>
  136. <span v-else>-</span>
  137. </template>
  138. </el-table-column>
  139. <el-table-column label="售后状态" align="center" prop="salesStatus" width="100">
  140. <template slot-scope="scope">
  141. <el-tag v-if="getDictLabel(salesStatusOptions, scope.row.salesStatus)"
  142. :type="salesStatusTagType(scope.row.salesStatus)">
  143. {{ getDictLabel(salesStatusOptions, scope.row.salesStatus) }}
  144. </el-tag>
  145. <span v-else>-</span>
  146. </template>
  147. </el-table-column>
  148. <el-table-column label="物流单号" align="center" prop="deliverySn" show-overflow-tooltip />
  149. <el-table-column label="提交时间" align="center" prop="createTime" width="160" />
  150. <el-table-column label="操作" align="center" fixed="right" width="100" class-name="small-padding fixed-width">
  151. <template slot-scope="scope">
  152. <el-button
  153. size="mini"
  154. type="text"
  155. @click="handleShow(scope.row)"
  156. v-hasPermi="['his:integralAfterSales:query']"
  157. >查看</el-button>
  158. </template>
  159. </el-table-column>
  160. </el-table>
  161. <pagination
  162. v-show="total > 0"
  163. :total="total"
  164. :page.sync="queryParams.pageNum"
  165. :limit.sync="queryParams.pageSize"
  166. @pagination="getList"
  167. />
  168. <!-- 售后详情抽屉 -->
  169. <el-drawer
  170. :with-header="false"
  171. size="75%"
  172. :title="drawerTitle"
  173. :visible.sync="drawerOpen"
  174. @close="getList"
  175. >
  176. <integral-after-sales-details ref="details" />
  177. </el-drawer>
  178. </div>
  179. </template>
  180. <script>
  181. import {
  182. listIntegralAfterSales,
  183. exportIntegralAfterSales
  184. } from "@/api/his/integralAfterSales";
  185. import { getCompanyList } from "@/api/company/company";
  186. import integralAfterSalesDetails from "./components/integralAfterSalesDetails";
  187. export default {
  188. name: "IntegralAfterSales",
  189. components: { integralAfterSalesDetails },
  190. data() {
  191. return {
  192. // 遮罩层
  193. loading: true,
  194. // 导出遮罩层
  195. exportLoading: false,
  196. // 显示搜索条件
  197. showSearch: true,
  198. // 总条数
  199. total: 0,
  200. // 售后单列表
  201. afterSalesList: [],
  202. // 选中数组
  203. ids: [],
  204. // 单个禁用
  205. single: true,
  206. // 多个禁用
  207. multiple: true,
  208. // 日期范围
  209. dateRange: [],
  210. // 抽屉
  211. drawerOpen: false,
  212. drawerTitle: "售后订单详情",
  213. // 公司下拉
  214. companyList: [],
  215. // 字典
  216. statusOptions: [],
  217. salesStatusOptions: [],
  218. serviceTypeOptions: [],
  219. // 查询参数
  220. queryParams: {
  221. pageNum: 1,
  222. pageSize: 10,
  223. orderCode: null,
  224. nickName: null,
  225. companyId: null,
  226. serviceType: null,
  227. status: null,
  228. salesStatus: null,
  229. deliverySn: null,
  230. beginTime: null,
  231. endTime: null
  232. }
  233. };
  234. },
  235. created() {
  236. this.getList();
  237. // 审核状态(status):已提交/已审核/已发货...
  238. this.getDicts("integral_after_sales_status").then(response => {
  239. this.statusOptions = response.data;
  240. });
  241. // 售后状态(salesStatus)与实体注释一致:0正常 1用户取消 2商家拒绝 3已完成
  242. this.salesStatusOptions = [
  243. { dictValue: '0', dictLabel: '正常' },
  244. { dictValue: '1', dictLabel: '用户取消' },
  245. { dictValue: '2', dictLabel: '商家拒绝' },
  246. { dictValue: '3', dictLabel: '已完成' }
  247. ];
  248. this.getDicts("store_after_sales_service_type").then(response => {
  249. this.serviceTypeOptions = response.data;
  250. });
  251. getCompanyList().then(response => {
  252. this.companyList = response.data;
  253. });
  254. },
  255. methods: {
  256. /** 获取字典标签(无匹配返回空串) */
  257. getDictLabel(options, value) {
  258. if (value === null || value === undefined || value === '') return '';
  259. const item = options.find(d => d.dictValue == value);
  260. return item ? item.dictLabel : '';
  261. },
  262. /** 审核状态标签类型 */
  263. statusTagType(status) {
  264. const typeMap = { 0: 'info', 1: 'warning', 2: 'warning', 3: 'primary', 4: 'danger', 5: 'success' };
  265. return typeMap[status] || 'info';
  266. },
  267. /** 售后状态标签类型 */
  268. salesStatusTagType(salesStatus) {
  269. const typeMap = { 0: '', 1: 'info', 2: 'danger', 3: 'success' };
  270. return typeMap[salesStatus] || 'info';
  271. },
  272. /** 服务类型标签类型 */
  273. serviceTypeTagType(serviceType) {
  274. const typeMap = { 0: 'warning', 1: 'danger' };
  275. return typeMap[serviceType] || 'info';
  276. },
  277. /** 查询售后单列表 */
  278. getList() {
  279. this.loading = true;
  280. const params = this.addDateRange(this.queryParams, this.dateRange);
  281. listIntegralAfterSales(params).then(response => {
  282. this.afterSalesList = response.rows;
  283. this.total = response.total;
  284. this.loading = false;
  285. }).catch(() => {
  286. this.loading = false;
  287. });
  288. },
  289. /** 搜索按钮操作 */
  290. handleQuery() {
  291. this.queryParams.pageNum = 1;
  292. this.getList();
  293. },
  294. /** 重置按钮操作 */
  295. resetQuery() {
  296. this.dateRange = [];
  297. this.resetForm("queryForm");
  298. this.queryParams.beginTime = null;
  299. this.queryParams.endTime = null;
  300. this.handleQuery();
  301. },
  302. /** 多选框选中数据 */
  303. handleSelectionChange(selection) {
  304. this.ids = selection.map(item => item.id);
  305. this.single = selection.length !== 1;
  306. this.multiple = !selection.length;
  307. },
  308. /** 查看详情 */
  309. handleShow(row) {
  310. this.drawerOpen = true;
  311. const id = row.id;
  312. setTimeout(() => {
  313. this.$refs.details.getDetails(id);
  314. }, 200);
  315. },
  316. /** 导出 */
  317. handleExport() {
  318. this.exportLoading = true;
  319. const params = this.addDateRange(this.queryParams, this.dateRange);
  320. exportIntegralAfterSales(params).then(response => {
  321. this.download(response.msg);
  322. this.exportLoading = false;
  323. }).catch(() => {
  324. this.exportLoading = false;
  325. });
  326. }
  327. }
  328. };
  329. </script>