index.vue 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843
  1. <template>
  2. <!-- 订单中心 -->
  3. <div class="orderPage flex-col">
  4. <s-header :name="$t('orderCenter.orderCenter')" :noback="false"></s-header>
  5. <div class="orderBox">
  6. <van-list v-model:loading="loading" v-model:error="error" :error-text="$t('public.requestFailed')"
  7. :finished="finished" :finished-text="$t('public.noMore')" offset="300" :immediate-check="false" @load="onLoad">
  8. <div class="main3 flex-col justify-center">
  9. <div class="outer1 flex-col justify-between">
  10. <div class="group4 flex-row justify-between">
  11. <div class="ImageText1 flex-col">
  12. <div class="outer2 flex-row justify-between">
  13. <div class="block1 flex-col"></div>
  14. <div class="TextGroup1 flex-col">
  15. <span class="txt1">{{ $t('orderCenter.dataOverview') }}</span>
  16. </div>
  17. </div>
  18. </div>
  19. <div class="ImageText2 flex-col" @click="searchClick()">
  20. <div class="group5 flex-row justify-between">
  21. <img class="icon2" src="../../assets/order/search.png" />
  22. <div class="TextGroup2 flex-col">
  23. <span class="txt2">{{ $t("common.search") }}</span>
  24. </div>
  25. </div>
  26. </div>
  27. </div>
  28. </div>
  29. </div>
  30. <dateSelectList @update="update($event)"></dateSelectList>
  31. <typeSelectList @upselectdata="upselectdata($event)"></typeSelectList>
  32. <div v-if="!noData(salesVolume, salesNumber, orderNumber)" class="o-plr-8 o-pt-15">
  33. <div class="outer5 flex-col">
  34. <div class="block5 flex-col">
  35. <div class="outerBox flex-row">
  36. <div class="main4 flex-col justify-between">
  37. <div class="main5 flex-row justify-center">
  38. <span class="word8">&yen;</span>
  39. <span class="word9">{{ salesVolume }}</span>
  40. </div>
  41. <span class="info5">{{ $t("home.totalIncome") }}</span>
  42. </div>
  43. <div class="TextGroup7 flex-col">
  44. <div class="mod3 flex-col justify-between">
  45. <span class="txt8">{{ salesNumber }}</span>
  46. <span class="info6">{{ $t("home.productNum") }}</span>
  47. </div>
  48. </div>
  49. <div class="TextGroup8 flex-col">
  50. <div class="outer6 flex-col justify-between">
  51. <span class="txt9">{{ orderNumber }}</span>
  52. <span class="word10">{{ $t("home.numberOfOrders") }}</span>
  53. </div>
  54. </div>
  55. </div>
  56. </div>
  57. </div>
  58. </div>
  59. <kNoData v-else></kNoData>
  60. <div class="o-mtb-10" style="height: 10px; background: #f5f5f5"></div>
  61. <!-- 时间 -->
  62. <div class="c-text-c c-text-18">
  63. {{ Format_time(searchParams.startDate, 'YYYY-MM-DD') }}--{{ Format_time(searchParams.endDate, 'YYYY-MM-DD')
  64. }}
  65. </div>
  66. <div class="group7 flex-col justify-center">
  67. <div class="main9 flex-col justify-between">
  68. <div class="wrap1 flex-row justify-between">
  69. <div class="ImageText7 flex-col">
  70. <div class="mod5 flex-row justify-between">
  71. <div class="block3 flex-col"></div>
  72. <div class="TextGroup7 flex-col">
  73. <span class="info3">{{ $t('orderCenter.orderDetails') }}</span>
  74. </div>
  75. </div>
  76. </div>
  77. <div class="ImageText8 flex-col" @click="gotoOrderExcel()">
  78. <div class="bd3 flex-row justify-between">
  79. <span class="info4 flex-col">{{ $t('orderCenter.exportToExcel') }}</span>
  80. <div class="outer3 flex-col"></div>
  81. </div>
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. <div class="section1 flex-col">
  87. <div class="group8 flex-col">
  88. <div class="section4 flex-col">
  89. <div v-for="(item, index) in orderList" :key="index">
  90. <div class="section5 flex-col" @click="orderClick(item)">
  91. <van-card :thumb="showSugerPhoto(item)">
  92. <template #title>
  93. <span class="word13">{{ $t('orderCenter.tradeName') }}:{{ item.productName }}</span>
  94. </template>
  95. <template #desc>
  96. <span class="word11">{{ $t('orderCenter.equipmentName') }}:{{ item.es }}</span>
  97. </template>
  98. <template #price>
  99. <div class="pricBox flex-row align-end" :class="{ orderError: item.status === 0 }">
  100. <span class="txt9">{{ item.statusText }}:</span>
  101. <span class="info5">&yen;</span>
  102. <span class="word12" v-if="item.status === 3">{{ item.price.toFixed(2) }}</span>
  103. <span class="word12" v-else>{{ item.refundAmount == null ? item.price.toFixed(2) : (item.price -
  104. item.refundAmount).toFixed(2) }}</span>
  105. <span class="word14">{{ $t('orderCenter.dividingDomesticService') }}:&yen;{{ showSubcom(item)
  106. }}</span>
  107. </div>
  108. </template>
  109. <template #price-top>
  110. <span class="time_01">{{ $t('orderCenter.paymentTime') }}:{{ showOrderTime(item, 1) }}</span>
  111. </template>
  112. <template #footer>
  113. <span v-if="item.status === 3">x{{ item.refundQuantity }}</span>
  114. <span v-else>x{{ item.refundQuantity == null ? item.productNumber : (item.productNumber -
  115. item.refundQuantity) }}</span>
  116. </template>
  117. </van-card>
  118. <!-- <div class="flex-row align-center">
  119. <div class="flex-col">
  120. <div class="flex-row align-center">
  121. <div class="main10 flex-col"></div>
  122. <span class="txt11">{{ showOrderTime(item, 1) }}</span>
  123. </div>
  124. <div class="flex-row align-center">
  125. <div class="sugerPhto" v-if="showSugerPhoto(item)">
  126. <img class="sugerImg" :src="showSugerPhoto(item)" />
  127. </div>
  128. <span class="word11">{{ $t('orderCenter.equipmentNo') }}:{{ showClientId(item) }}</span>
  129. <span class="word13">{{ $t('orderCenter.tradeName') }}:{{ item.productName }}</span>
  130. </div>
  131. <div class="flex-row align-center">
  132. <span class="word11">{{ $t('orderCenter.equipmentName') }}:{{ item.es }}</span>
  133. <span class="word13"></span>
  134. </div>
  135. <div class="flex-row align-end">
  136. <div class="pricBox flex-row align-end" :class="{ orderError: item.status === 0 }">
  137. <span class="txt9">{{ item.statusText }}:</span>
  138. <span class="info5">&yen;</span>
  139. <span class="word12">{{ item.price }}</span>
  140. </div>
  141. <span class="word14">{{ $t('orderCenter.dividingDomesticService') }}:&yen;{{ showSubcom(item)
  142. }}</span>
  143. </div>
  144. </div>
  145. </div> -->
  146. <div v-if="typeof item.status === 'undefined'" class="main11 flex-col orderSuccess"></div>
  147. <div v-else class="main11 flex-col" :class="{
  148. orderSuccess: item.status === 1,
  149. orderError: item.status === 0,
  150. refunding: item.status === 2,
  151. refunded: item.status === 3,
  152. }"></div>
  153. </div>
  154. <!-- <div class="section6 flex-col"></div> -->
  155. </div>
  156. </div>
  157. </div>
  158. </div>
  159. </van-list>
  160. </div>
  161. <!-- 搜索弹出框 -->
  162. <orderSearch ref="searchRef" @search="search($event)"></orderSearch>
  163. <!-- 退款弹窗 -->
  164. <van-popup v-model:show="refundType" position="bottom" round>
  165. <div class="refundBox flex-col">
  166. <div class="section1 flex-col">
  167. <div class="group3 flex-col">
  168. <div class="TextGroup1 l-flex-center">
  169. <div class="outer1 flex-col">
  170. <!-- <span class="txt4">这里是设备名称</span> -->
  171. <span class="info1">{{ $t('orderCenter.business') }}</span>
  172. <span class="txt5">+ {{ refundObject.refundAmount == null ? refundObject.price.toFixed(2) :
  173. (refundObject.price - refundObject.refundAmount).toFixed(2) }}</span>
  174. </div>
  175. </div>
  176. <div class="layer1 flex-col"></div>
  177. <div class="layer2 flex-row justify-between">
  178. <span class="info2">{{ $t('orderCenter.accountBalance') }}</span>
  179. <span class="txt6">{{ accountDetail.altAvilBalance }}</span>
  180. </div>
  181. <div class="layer3 flex-row justify-between">
  182. <span class="word2">{{ $t('orderCenter.orderNo') }}</span>
  183. <span class="info3">{{ refundObject.sn }}</span>
  184. </div>
  185. <div class="layer3 flex-row justify-between">
  186. <span class="word2">{{ $t('orderCenter.commodity') }}</span>
  187. <span class="info3">{{ refundObject.productName }}</span>
  188. </div>
  189. <div class="layer4 flex-row justify-between">
  190. <span class="word3">{{ $t('orderCenter.distribution') }}</span>
  191. <span class="word4">{{ showSubcom(refundObject) }}</span>
  192. </div>
  193. <div class="layer4 flex-row justify-between">
  194. <span class="word3">{{ $t('orderCenter.equipmentNo') }}</span>
  195. <span class="word4">{{ refundObject.clientId }}</span>
  196. </div>
  197. <div class="layer5 flex-row justify-between">
  198. <span class="txt7">{{ $t('orderCenter.state') }}</span>
  199. <span class="word5">{{ showStatus(refundObject) }}</span>
  200. </div>
  201. <div class="layer6 flex-row justify-between">
  202. <span class="word6">{{ $t('orderCenter.paymentMethod') }}</span>
  203. <span class="word7">{{ showPayType(refundObject) }}</span>
  204. </div>
  205. <div class="layer6 flex-row justify-between">
  206. <span class="word6">{{ $t('orderCenter.creationTime') }}</span>
  207. <span class="word7">{{ showOrderTime(refundObject, 2) }}</span>
  208. </div>
  209. <div v-if="refundObject.status === 3" class="layer7 flex-row justify-between">
  210. <span class="word8">{{ $t('orderCenter.refunded') }}</span>
  211. <span class="info4">{{ refundObject.refundAmount }}</span>
  212. </div>
  213. <!-- 发起退款 -->
  214. <!-- 非已付款订单,线下订单要隐藏按钮 -->
  215. <van-button size="small"
  216. v-if="(refundObject.status === 1 && user.ifForeign === '0') || (refundObject.status === 1 && user.ifForeign === '1' && refundObject.isAir === '1')"
  217. @click="noticeClk(refundObject)" round type="primary" style="margin-top: 20px;">
  218. {{ $t('orderCenter.initiateRefund') }}
  219. </van-button>
  220. </div>
  221. </div>
  222. </div>
  223. </van-popup>
  224. <!-- 退款弹窗 -->
  225. <kDialog :isCloseForConfirm="false" :dialogTitle="$t('orderCenter.refundTip')"
  226. :confirmBtnTxt="$t('orderCenter.refundSubmit')" ref="kDialogRef" @confirmclk="confirmClk">
  227. <template #content>
  228. <div class="cust_vantBorder l-flex-RC">
  229. <div v-for="(item, index) in orderDetails" :key="index" class="card01">
  230. <van-checkbox v-model="isChecked[index]" @change="checkGood(index)" icon-size="20px"></van-checkbox>
  231. <van-card :price="item.price.toFixed(2)" :title="item.productName" :thumb="showSugarPic(item.productNo)">
  232. <template #footer>
  233. <van-stepper v-model="refundNum[index]" @plus="plusRefundGood(index)" @minus="minusRefundGood(index)"
  234. theme="round" button-size="22" disable-input
  235. :max="item.refundQuantity == null ? item.productNumber : (item.productNumber - item.refundQuantity)" />
  236. </template>
  237. </van-card>
  238. </div>
  239. </div>
  240. <div class="o-mt-5" style="height: 1px; background: #d7d7e2"></div>
  241. <div class="btnFooter">
  242. <van-checkbox class="checkAllBtn o-mt-5" v-model="checkedAll" @click="checkAll">全选</van-checkbox>
  243. <div class="o-mt-5">
  244. <span class="">{{ $t('orderCenter.totalRefund') }}:</span>
  245. <span class="totalRefund o-pr-15">&yen; {{ totalRefund.toFixed(2) }}</span>
  246. </div>
  247. </div>
  248. </template>
  249. </kDialog>
  250. </div>
  251. </template>
  252. <script>
  253. import { Api_getOnlineExport } from "../../service/order";
  254. // 导入接口
  255. import { getAdminMch } from "../../service/merchantManage";
  256. // 导入弹窗
  257. import kDialog from "../../components/commom/kDialog/index.vue";
  258. // 导入无数据组件
  259. import { Dialog } from 'vant';
  260. import kNoData from "../../components/commom/kNoData/index.vue";
  261. import { onMounted, reactive, ref } from "vue";
  262. import sHeader from "../../components/SimpleHeader";
  263. import orderSearch from "./orderSearch.vue";
  264. import { getOrderList, refundOrder } from "../../service/order/index";
  265. import { Toast } from "vant";
  266. import { getLoginUser, $M_IsDate, Format_time, $M_ExportFile, styleUrl } from "../../common/js/utils";
  267. import { getHuifuId } from "../../service/huifuMch/index";
  268. import dateUtil from "../../utils/dateUtil";
  269. import dateSelectList from "../../components/dateSelectList";
  270. import typeSelectList from "../../components/typeSelectList";
  271. import { getStatistics } from "../../service/home";
  272. import { useI18n } from "vue-i18n";
  273. export default {
  274. name: "order",
  275. components: { sHeader, orderSearch, dateSelectList, typeSelectList, kNoData, kDialog },
  276. setup() {
  277. // 批量修改弹窗
  278. const kDialogRef = ref(null);
  279. // 订单明细
  280. const orderDetails = ref([]);
  281. // 退款商品选择状态
  282. const isChecked = ref([]);
  283. // 全选状态
  284. const checkedAll = ref(false);
  285. // 退款总额
  286. const totalRefund = ref(0);
  287. // 退款商户数量
  288. const refundNum = ref([]);
  289. // 加载状态
  290. // const isLoading = ref(false);
  291. // 监控退款选择框状态
  292. const checkGood = (index) => {
  293. if (isChecked.value[index]) {
  294. totalRefund.value = parseFloat((totalRefund.value + (refundNum.value[index] * orderDetails.value[index].price)).toFixed(2));
  295. } else {
  296. if (totalRefund.value > 0) {
  297. totalRefund.value = parseFloat((totalRefund.value - (refundNum.value[index] * orderDetails.value[index].price)).toFixed(2));
  298. }
  299. }
  300. // 如果都为true,都为全选
  301. if (isChecked.value.every((value) => value === true)) {
  302. checkedAll.value = true;
  303. } else {
  304. checkedAll.value = false;
  305. }
  306. }
  307. // 点击增加按钮
  308. const plusRefundGood = (index) => {
  309. if (isChecked.value[index]) {
  310. totalRefund.value = parseFloat((totalRefund.value + orderDetails.value[index].price).toFixed(2));
  311. }
  312. }
  313. // 点击减少按钮
  314. const minusRefundGood = (index) => {
  315. if (isChecked.value[index]) {
  316. totalRefund.value = parseFloat((totalRefund.value - orderDetails.value[index].price).toFixed(2));
  317. }
  318. }
  319. // 点击弹出退款弹窗
  320. const noticeClk = (row) => {
  321. if (row.orderDetails.length > 0) {
  322. isChecked.value = [];
  323. orderDetails.value = [];
  324. refundNum.value = [];
  325. checkedAll.value = false;
  326. totalRefund.value = 0;
  327. // cofficentForm.price = row.price;
  328. // cofficentForm.maxPrice = row.price;
  329. cofficentForm.id = row.id;
  330. // cofficentForm.maxNumber = row.productNumber;
  331. // cofficentForm.productNumber = row.productNumber;
  332. row.orderDetails.forEach(item => {
  333. if (item.refundStatus == '1' || item.refundStatus == '2') {
  334. orderDetails.value.push(item);
  335. if (item.refundQuantity != null) {
  336. refundNum.value.push(item.productNumber - item.refundQuantity);
  337. } else {
  338. refundNum.value.push(item.productNumber);
  339. }
  340. }
  341. });
  342. // 根据orderDetails的长度,向isChecked添加相应数量的false
  343. isChecked.value = Array.from({ length: orderDetails.value.length }, () => false);
  344. kDialogRef.value.openDialog();
  345. } else {
  346. Toast("请联系管理员");
  347. return;
  348. }
  349. };
  350. // 点击全选按钮
  351. const checkAll = () => {
  352. isChecked.value.forEach((item, index) => {
  353. if (isChecked.value[index]) {
  354. isChecked.value[index] = !isChecked.value[index]
  355. checkedAll.value = false;
  356. } else {
  357. isChecked.value[index] = !isChecked.value[index]
  358. checkedAll.value = true;
  359. }
  360. })
  361. }
  362. // 点击确定按钮
  363. const confirmClk = () => {
  364. cofficentForm.note = "";
  365. cofficentForm.productNumber = 0;
  366. cofficentForm.price = 0;
  367. isChecked.value.forEach((isCheckedValue, index) => {
  368. if (isCheckedValue) {
  369. cofficentForm.note = cofficentForm.note + orderDetails.value[index].productNo + "-" + refundNum.value[index] + ","
  370. cofficentForm.productNumber = cofficentForm.productNumber + refundNum.value[index];
  371. }
  372. })
  373. cofficentForm.price = totalRefund.value;
  374. if (cofficentForm.note === "" || cofficentForm.price === 0 || cofficentForm.price === "") {
  375. Toast(t('orderCenter.refundPlace'));
  376. return;
  377. } else {
  378. Dialog.confirm({
  379. // title: "提示",
  380. message: t('orderCenter.refundCheck'),
  381. }).then(() => {
  382. // isLoading.value = true; // 开始加载
  383. refundAjax();
  384. // isLoading.value = false; // 加载完成
  385. kDialogRef.value.closeDialog();
  386. }).catch(() => {
  387. return;
  388. });
  389. }
  390. }
  391. // 退款操作
  392. const refundAjax = async () => {
  393. try {
  394. const { data } = await refundOrder(cofficentForm);
  395. if (data.code && data.code !== 'B0001') {
  396. Dialog.alert({
  397. message: t('orderCenter.refundSucceeded'),
  398. }).then(() => {
  399. refundType.value = false;
  400. // on close
  401. orderList.value = [];
  402. search({});
  403. });
  404. } else {
  405. Toast.fail(data.message);
  406. }
  407. } catch (error) {
  408. Toast.fail(t('orderCenter.requestFailed'));
  409. }
  410. };
  411. // 修改的价格
  412. const cofficentForm = reactive({
  413. price: 0,
  414. id: "",
  415. productNumber: 0,
  416. note: 0
  417. });
  418. // 引入语言
  419. const { t } = useI18n();
  420. // 订单商品图片路径处理
  421. const showSugerPhoto = (row) => {
  422. if (row.orderDetails != null) {
  423. if (row.orderDetails.length > 0) {
  424. return require(`../../assets/order/spunSugar/goods/${row.orderDetails[0].productNo}.png`);
  425. } else {
  426. if (row.productNo != null) {
  427. return require(`../../assets/order/spunSugar/goods/${row.productNo}.png`);
  428. }
  429. if (row.machineType == null || row.machineType == '0') {
  430. return require(`../../assets/order/spunSugar/goods/A01.png`);
  431. } else {
  432. return require(`../../assets/order/spunSugar/goods/B01.png`);
  433. }
  434. }
  435. } else {
  436. if (row.machineType == null || row.machineType == '0') {
  437. return require(`../../assets/order/spunSugar/goods/A01.png`);
  438. } else {
  439. return require(`../../assets/order/spunSugar/goods/B01.png`);
  440. }
  441. }
  442. };
  443. // 订单明细商品图片路径处理
  444. const showSugarPic = (row) => {
  445. return require(`../../assets/order/spunSugar/goods/${row}.png`);
  446. };
  447. // 如果是空数据
  448. const noData = (volumes, nums) => {
  449. if (!volumes && !nums) {
  450. return true;
  451. }
  452. return false;
  453. };
  454. const user = getLoginUser();
  455. const searchRef = ref(null);
  456. const huifuId = ref(null);
  457. const orderList = ref([]);
  458. const orderTotal = ref(0);
  459. const loading = ref(true);
  460. const error = ref(false);
  461. const finished = ref(false);
  462. // 滚动加载
  463. const onLoad = () => {
  464. if (!finished.value) {
  465. loading.value = true;
  466. searchParams.current = searchParams.current + 1;
  467. getList();
  468. }
  469. };
  470. // 页面列表查询参数
  471. let searchParams = reactive({
  472. adminId: "", // 用户账户id
  473. userName: "", // 用户名 String 没有值时传null
  474. adminType: "", // 判断是否查全部商户 当用户为商家时,“本商户”这个选项为“所有下级用户”传入一个“all”的值,其他情况传null
  475. type: user.ifForeign, // 订单类型 用来区分是国内、海外订单,0:国内,1:海外。默认值一般要根据当前登录用户的类型去选择。区分的参数是admin里ifForeign的值。ifForeign=0则type=0.
  476. // ifForeign现在用于区分国内0,海外1
  477. // isAir海外又分为两种情况,0/null为线下,1是线上
  478. payType: "", // 支付方式 全部时传null 0:无需支付 1:硬币 2:纸币 3:硬币+纸币 4:信用卡 5:电子支付 ALIPAY_NATIVE:支付宝主扫 WEIXIN_NATIVE:微信主扫 ALIPAY_CARD:支付宝反扫 WEIXIN_CARD:微信反扫
  479. productNo: "", // 商品的标识 全部时传null。 Tproductd对象的属性no的值。
  480. clientId: "", // 设备编号 String
  481. dateType: "0", // 所选时间类型 String 0:创建时间 1:退款时间
  482. startDate: "", // 开始时间 Date
  483. endDate: "", // 结束时间 Date
  484. current: 0, // 页数
  485. size: 15, // 页大小
  486. status: "",//支付状态
  487. companyType: "", // 公司平台
  488. machineType: "", // 设备类型
  489. ifForeign: "",
  490. });
  491. let chartType = "day";
  492. // 获取订单列表数据
  493. const getList = async () => {
  494. finished.value = false;
  495. getStatisticsFun();
  496. // 因为订单的时间格式不一样
  497. const params = Object.assign({}, searchParams);
  498. if ($M_IsDate(params.startDate)) {
  499. params.startDate = dateUtil.formateDate(
  500. new Date(params.startDate),
  501. "yyyy-MM-dd hh:mm:ss"
  502. );
  503. } else {
  504. params.startDate = "";
  505. }
  506. if ($M_IsDate(params.endDate)) {
  507. params.endDate = dateUtil.formateDate(
  508. new Date(params.endDate),
  509. "yyyy-MM-dd hh:mm:ss"
  510. );
  511. } else {
  512. params.endDate = "";
  513. }
  514. // 获取订单列表
  515. const { data } = await getOrderList(Object.assign({}, params));
  516. if (data.code === "00000") {
  517. if (data.data.total === 0) {
  518. finished.value = true;
  519. } else {
  520. // orderTotal.value = data.data.total;
  521. if (params.current === 1) {
  522. orderList.value = [];
  523. orderTotal.value = 0;
  524. }
  525. // 列表值叠加
  526. if (data.data.records.length > 0) {
  527. orderList.value = orderList.value.concat(
  528. data.data.records.map((item) => {
  529. return {
  530. ...item,
  531. statusText:
  532. item.altInfo != null
  533. ? t('orderCenter.onlinePayment')
  534. : t('orderCenter.offlinePayment'),
  535. };
  536. })
  537. );
  538. orderTotal.value = data.data.records.length + orderTotal.value;
  539. if (orderTotal.value === data.data.total) {
  540. finished.value = true;
  541. }
  542. } else {
  543. finished.value = true;
  544. }
  545. }
  546. loading.value = false;
  547. } else {
  548. // error.value = true;
  549. Toast.fail("数据加载失败");
  550. }
  551. };
  552. // 搜索表单点击
  553. const searchClick = () => {
  554. searchRef.value.showSearch();
  555. };
  556. // 搜索表单初始化页面及状态查询列表
  557. const search = (data) => {
  558. searchParams = Object.assign(searchParams, data);
  559. // 这个会导致请求两次接口
  560. // finished.value = false;
  561. orderList.value = [];
  562. loading.value = true;
  563. searchParams.current = 1;
  564. getList();
  565. };
  566. // 今日、明日、本周、本月、其他时间选择回调
  567. const update = (uDate) => {
  568. chartType = uDate.chartType;
  569. searchParams = Object.assign(searchParams, uDate);
  570. searchParams.type = searchParams.ifForeign;
  571. search();
  572. };
  573. // 商户、支付方式、设备、商品选择回调
  574. const upselectdata = (uSData) => {
  575. // console.log('uSData', uSData)
  576. searchParams = Object.assign(searchParams, uSData);
  577. // console.log('searchParams', searchParams)
  578. searchParams.type = searchParams.ifForeign;
  579. search();
  580. };
  581. // 初始化页面获取列表
  582. onMounted(async () => {
  583. // 加载样式
  584. styleUrl('orderCenter');
  585. // orderList.value = [];
  586. // searchParams.current = 1;
  587. if (user) {
  588. searchParams.adminId = user.id;
  589. searchParams.userName = user.username;
  590. const { data } = await getHuifuId({
  591. adminId: user.id,
  592. });
  593. if (data.code === '00000') {
  594. if (data.data != null) {
  595. huifuId.value = data.data.huifuId;
  596. }
  597. }
  598. // 获取当天
  599. let now = new Date();
  600. let startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0);
  601. searchParams.startDate = dateUtil.formateDate(startDate, "yyyy-MM-dd hh:mm:ss");
  602. let endDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59);
  603. searchParams.endDate = dateUtil.formateDate(endDate, "yyyy-MM-dd hh:mm:ss");
  604. // finished.value = false;
  605. // loading.value = true;
  606. // getList();
  607. onLoad();
  608. addEventListener('load', onLoad);
  609. // 获取账户详情
  610. if (user.ifForeign === '0') {
  611. getAccountDetail(user.id);
  612. }
  613. }
  614. });
  615. // 查询是否有退款权限
  616. const isRefund = user.menuCodeList.some((item) => {
  617. return item === "M16";
  618. });
  619. // 跳转订单导出
  620. const gotoOrderExcel = async () => {
  621. // 显示加载框
  622. const loadingInstance = Toast.loading({
  623. message: '加载中...',
  624. forbidClick: true,
  625. });
  626. try {
  627. const { headers, data } = await Api_getOnlineExport(searchParams);
  628. // 请求完成后隐藏加载框
  629. loadingInstance.clear();
  630. $M_ExportFile(data, headers);
  631. // 处理返回的数据
  632. } catch (error) {
  633. // 请求发生错误时隐藏加载框
  634. loadingInstance.clear();
  635. // 处理错误情况
  636. console.error(error);
  637. }
  638. };
  639. // 订单详情-退款弹窗
  640. const refundType = ref(false);
  641. const refundObject = ref({});
  642. const orderClick = (item) => {
  643. //查询商户余额,要用admin的type去区分 TODO
  644. refundObject.value = item;
  645. refundType.value = true;
  646. };
  647. const accountDetail = ref({});
  648. // 获取账户详情
  649. const getAccountDetail = (id) => {
  650. getAdminMch({ id }).then(res => {
  651. accountDetail.value = res.data.data;
  652. })
  653. };
  654. // 订单时间格式转换
  655. const showOrderTime = (item, idx) => {
  656. if (idx === 1) {
  657. switch (item.status) {
  658. case 1:
  659. return dateUtil.timeZoneDate(new Date(dateUtil.formateDate(new Date(item.payDate), "yyyy-MM-dd hh:mm:ss")));
  660. case 3:
  661. return dateUtil.timeZoneDate(new Date(dateUtil.formateDate(new Date(item.refundDate), "yyyy-MM-dd hh:mm:ss")));
  662. default:
  663. return dateUtil.timeZoneDate(new Date(dateUtil.formateDate(new Date(item.createDate), "yyyy-MM-dd hh:mm:ss")));
  664. }
  665. } else {
  666. return item && item.createDate
  667. ? dateUtil.timeZoneDate(new Date(dateUtil.formateDate(new Date(item.createDate), "yyyy-MM-dd hh:mm:ss")))
  668. : "";
  669. }
  670. };
  671. // 设备编号格式转换
  672. const showClientId = (item) => {
  673. return item && item.clientId
  674. ? item.clientId.substring(item.clientId.length - 6)
  675. : "";
  676. };
  677. // 计算分佣
  678. const showSubcom = (item) => {
  679. let subcom = "0";
  680. if (item.altInfo) {
  681. const altInfo = JSON.parse(item.altInfo);
  682. if (altInfo && altInfo.length > 0) {
  683. // altInfo这个属性里,最后一个实体的altAmount的值就是他的分佣。
  684. subcom = altInfo[altInfo.length - 1]['altAmount'];
  685. }
  686. }
  687. if (item.acctSplitBunch) {
  688. const data = JSON.parse(item.acctSplitBunch);
  689. const targetObj = data.acct_infos.find(obj => obj.huifu_id === huifuId.value);
  690. if (targetObj) {
  691. subcom = targetObj.div_amt;
  692. }
  693. }
  694. return subcom;
  695. };
  696. // 弹窗订单状态
  697. const showStatus = (item) => {
  698. if (typeof item.status === "undefined") {
  699. return t('orderCenter.paymentSucceeded');
  700. } else {
  701. if (item.status === 0) {
  702. return t('orderCenter.unpaid');
  703. }
  704. if (item.status === 1) {
  705. return t('orderCenter.paid');
  706. }
  707. if (item.status === 2) {
  708. return t('orderCenter.refundInProgress');
  709. }
  710. if (item.status === 3) {
  711. return t('orderCenter.refunded');
  712. }
  713. }
  714. return item;
  715. };
  716. const paySouerList = [
  717. { text: t('orderCenter.whole'), values: null },
  718. { text: t('orderCenter.noPaymentRequired'), values: 0 },
  719. { text: t('orderCenter.coin'), values: 1 },
  720. { text: t('orderCenter.notes'), values: 2 },
  721. { text: t('orderCenter.coinsNotes'), values: 3 },
  722. { text: t('orderCenter.creditCard'), values: 4 },
  723. { text: t('orderCenter.electronicPayment'), values: 5 },
  724. { text: t('orderCenter.mainSweepOfAlipay'), values: "ALIPAY_NATIVE" },
  725. { text: t('orderCenter.weChatScanning'), values: "WEIXIN_NATIVE" },
  726. { text: t('orderCenter.antiScanningOfAlipay'), values: "ALIPAY_CARD" },
  727. { text: t('orderCenter.weChatBackScanning'), values: "WEIXIN_CARD" },
  728. ];
  729. // 弹窗支付上述
  730. const showPayType = (item) => {
  731. const payType = user.ifForeign === "0" ? item.frpCode : item.payType;
  732. const paySoure = paySouerList.filter((i) => i.values === payType);
  733. if (paySoure.length > 0) {
  734. return paySoure[0].text;
  735. } else {
  736. return "";
  737. }
  738. };
  739. const salesVolume = ref(0);
  740. const salesNumber = ref(0);
  741. const orderNumber = ref(0);
  742. // 查询图表
  743. const getStatisticsFun = async () => {
  744. // console.log('searchParams', searchParams)
  745. const params = {
  746. adminId: user.id,
  747. chartType: chartType,
  748. endDate: searchParams.endDate,
  749. ifForeign: searchParams.ifForeign == '' ? user.ifForeign : searchParams.ifForeign,
  750. startDate: searchParams.startDate,
  751. userName: searchParams.userName,
  752. clientId:
  753. searchParams.clientId === "" ? null : searchParams.clientId,
  754. equipmentId:
  755. searchParams.equipmentId === "" ? null : searchParams.equipmentId,
  756. payType:
  757. searchParams.payType === "" ? null : searchParams.payType,
  758. companyType: searchParams.companyType,
  759. machineType: searchParams.machineType,
  760. isAir: searchParams.isAir === "" ? null : searchParams.isAir,
  761. };
  762. const { data } = await getStatistics(params);
  763. if (data.code && data.data) {
  764. salesVolume.value = 0;
  765. salesNumber.value = 0;
  766. orderNumber.value = 0;
  767. data.data.series[0].data.forEach((item) => {
  768. salesNumber.value = parseInt(salesNumber.value + item);
  769. });
  770. data.data.series[1].data.forEach((item) => {
  771. salesVolume.value = parseInt(salesVolume.value + item);
  772. });
  773. data.data.series[2].data.forEach((item) => {
  774. orderNumber.value = parseInt(orderNumber.value + item);
  775. });
  776. }
  777. };
  778. return {
  779. user,
  780. loading,
  781. error,
  782. finished,
  783. onLoad,
  784. orderList,
  785. orderTotal,
  786. searchRef,
  787. searchClick,
  788. search,
  789. update,
  790. upselectdata,
  791. gotoOrderExcel,
  792. refundType,
  793. refundObject,
  794. orderClick,
  795. showSugerPhoto,
  796. showOrderTime,
  797. showClientId,
  798. showSubcom,
  799. showStatus,
  800. showPayType,
  801. salesVolume,
  802. salesNumber,
  803. orderNumber,
  804. noData,
  805. kDialogRef,
  806. noticeClk,
  807. confirmClk,
  808. cofficentForm,
  809. accountDetail,
  810. Format_time,
  811. searchParams,
  812. orderDetails,
  813. huifuId,
  814. showSugarPic,
  815. isChecked,
  816. refundNum,
  817. checkAll,
  818. checkedAll,
  819. totalRefund,
  820. checkGood,
  821. plusRefundGood,
  822. minusRefundGood,
  823. // isLoading,
  824. isRefund,
  825. };
  826. },
  827. };
  828. </script>
  829. <style lang="less" scoped>
  830. @import "../../common/style/common.less";
  831. @import "../../styles/orderCenter/index.less";
  832. </style>