index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. <template>
  2. <!-- 订单分析 -->
  3. <div class="orderExpotPage flex-col">
  4. <s-header :name="$t('orderExport.orderAnalysis')" :noback="false"></s-header>
  5. <div class="Body flex-col">
  6. <div class="mod3 flex-col">
  7. <div class="group1 flex-col">
  8. <div class="titleBox flex-col">
  9. <div class="layer2 flex-row">
  10. <div class="section5 flex-col"></div>
  11. <div class="TextGroup2 flex-col">
  12. <span class="txt4">{{ $t("orderExport.dataOverview") }}</span>
  13. </div>
  14. </div>
  15. </div>
  16. <div class="dateSelectBox">
  17. <dateSelectList @update="update($event)"></dateSelectList>
  18. </div>
  19. <div class="l-f l-flex-e o-plr-15 o-pt-10">
  20. <span class="o-mr-6 c-text-13 c-text-color">{{ $t("orderExport.groupType") }}:</span>
  21. <kTabs @tabchg="tabChg" :tabList="tabList"></kTabs>
  22. </div>
  23. <div class="mod7 flex-col">
  24. <div class="box1 flex-col justify-between">
  25. <div class="group4 l-flex-between">
  26. <div class="ImageText2 l-flex-RC">
  27. <div class="mod8 l-flex-RC">
  28. <div class="group5 flex-col"></div>
  29. <div class="TextGroup2 flex-col">
  30. <span class="txt1 c-text-w6">{{
  31. $t("orderExport.orderDetails")
  32. }}</span>
  33. </div>
  34. </div>
  35. </div>
  36. <div class="l-flex-RC">
  37. <div class="c-text-13 l-flex-RC text5">
  38. <span @click="noticeClk" class="">{{
  39. $t("orderExport.clickFilter")
  40. }}</span>
  41. <div class="outer4 flex-col o-ml-6"></div>
  42. </div>
  43. <div @click="exportOrder()" class="c-text-13 l-flex-RC o-ml-20 c-text-color">
  44. <span class="">{{
  45. $t("orderExport.exportToExcel")
  46. }}</span>
  47. <div class="outer4 flex-col o-ml-6"></div>
  48. </div>
  49. </div>
  50. </div>
  51. <img class="img2" referrerpolicy="no-referrer"
  52. src="../../assets/line.png" />
  53. </div>
  54. </div>
  55. <!-- <van-pull-refresh disabled v-model="refreshing" @refresh="onRefresh"> -->
  56. <van-list v-model:loading="loading" v-model:error="error" :error-text="$t('public.requestFailed')"
  57. :finished="finished" :finished-text="$t('public.noMore')" @load="onLoad"
  58. :immediate-check="false">
  59. <div v-for="(item, index) in tableData" :key="index" class="orderItem">
  60. <div class="mod9 flex-row">
  61. <!-- 自定义货币符号¥ -->
  62. <!-- <span class="info7">&yen;</span> -->
  63. <span class="word9">{{ $t("orderExport.totalSales") }}</span>
  64. <span class="info7">{{ currencySymbol }}</span>
  65. <span class="info8">{{ item.priceTotal }}</span>
  66. </div>
  67. <div class="mod10 flex-row">
  68. <span class="txt3 o-mr-10">{{ item.username }}</span>
  69. <span class="txt4 c-text-line1">{{ item.name }}</span><span class="txt4 c-text-line1">,{{ item.phone
  70. }}</span>
  71. </div>
  72. <span class="info9">{{ $t("orderExport.address") }}:{{ item.address }}</span>
  73. <div class="mod11 flex-col">
  74. <span v-if="type == 2" class="txt5">{{ item.equipmentTotal }}{{ $t("orderExport.machines") }},{{
  75. $t("orderExport.superior")
  76. }}:{{ item.lastUsername }}</span>
  77. <div v-else class="txt5 l-flex-RC">
  78. <div>{{ item.equipmentType }}</div>
  79. <div class="lineCon o-mlr-6"></div>
  80. <div>{{ item.clientId }}</div>
  81. </div>
  82. </div>
  83. </div>
  84. </van-list>
  85. <!-- </van-pull-refresh> -->
  86. </div>
  87. </div>
  88. </div>
  89. <!-- 筛选弹窗 -->
  90. <kDialog :dialogTitle="$t('orderExport.searchPop.title')" :cancelBtnTxt="$t('orderExport.searchPop.clearFilter')"
  91. :confirmBtnTxt="$t('orderExport.searchPop.filter')" ref="kDialogRef" @confirmclk="confirmClk"
  92. :isCloseForCancel="false" @cancelclk="cancelClk">
  93. <template #content>
  94. <div class="cust_vantBorder">
  95. <van-field clearable v-model="searchForm.orderNo" :placeholder="$t('orderExport.searchPop.orderNoPlace')"
  96. :label="$t('orderExport.searchPop.orderNo')" />
  97. <van-field clearable v-model="searchForm.busiName" :placeholder="$t('orderExport.searchPop.busiNamePlace')"
  98. :label="$t('orderExport.searchPop.busiName')" />
  99. <van-field @click-input="changeTypeInpClk" readonly clearable v-model="searchForm.ifForeignName"
  100. :placeholder="$t('orderExport.searchPop.mainOverPlace')" :label="$t('orderExport.searchPop.mainOver')">
  101. <template #right-icon>
  102. <div class="l-flex-RC">
  103. <van-icon v-if="searchForm.ifForeignName" @click="searchForm.ifForeignName = '';
  104. searchForm.ifForeign = '';" class="o-mr-6" name="clear" />
  105. <van-icon @click="changeTypeInpClk" name="arrow-down" />
  106. </div>
  107. </template>
  108. </van-field>
  109. <van-field v-if="isAdmin()" @click-input="companyTypeInpClk" readonly clearable
  110. v-model="searchForm.companyTypeName" :placeholder="$t('orderExport.searchPop.companyTypePlaceholder')"
  111. :label="$t('orderExport.searchPop.companyTypeLabel')">
  112. <template #right-icon>
  113. <div class="l-flex-RC">
  114. <van-icon v-if="searchForm.companyTypeName" @click="
  115. searchForm.companyTypeName = '';
  116. searchForm.companyType = '';
  117. " class="o-mr-6" name="clear" />
  118. <van-icon @click="companyTypeInpClk" name="arrow-down" />
  119. </div>
  120. </template>
  121. </van-field>
  122. </div>
  123. </template>
  124. </kDialog>
  125. <!-- 大陆或海外弹窗 -->
  126. <van-popup v-model:show="changeTypeShow" position="bottom">
  127. <van-picker :title="$t('orderExport.searchPop.mainOverPlace')" :columns="changeTypePopList"
  128. :columns-field-names="changeTypePopFieldName" @confirm="changeTypePopConfirm" @cancel="changeTypeShow = false" />
  129. </van-popup>
  130. <!-- 公司平台弹窗 -->
  131. <van-popup v-model:show="companyTypeShow" position="bottom">
  132. <van-picker :title="$t('orderExport.searchPop.companyTypePlaceholder')"
  133. :columns="companyTypePopList" :columns-field-names="changeTypePopFieldName" @confirm="companyTypePopConfirm"
  134. @cancel="companyTypeShow = false" />
  135. </van-popup>
  136. </div>
  137. </template>
  138. <script>
  139. import { getOrderList, Api_getOrderExport } from "@/service/orderExport";
  140. import { onMounted, reactive, toRefs, ref } from "vue";
  141. import sHeader from "@/components/SimpleHeader";
  142. import { getLoginUser, $M_ExportFile } from "@/common/js/utils";
  143. import dateSelectList from "@/components/dateSelectList";
  144. import dateUtil from "@/utils/dateUtil";
  145. import kTabs from "@/components/commom/kTabs/index.vue";
  146. import { useI18n } from "vue-i18n";
  147. import kDialog from "@/components/commom/kDialog/index.vue";
  148. import moment from 'moment';
  149. import { styleUrl } from "../../common/js/utils";
  150. import { showFailToast } from "vant";
  151. export default {
  152. name: "orderExport",
  153. components: { sHeader, dateSelectList, kTabs, kDialog },
  154. setup() {
  155. // 分页
  156. const pageNo = ref(1);
  157. const pageSize = ref(10);
  158. // let ruleData = reactive({
  159. // tableData: [],
  160. // });
  161. const tableData = ref([]);
  162. const orderTotal = ref(0);
  163. // 上拉刷新
  164. const loading = ref(true);
  165. const finished = ref(false);
  166. const error = ref(false);
  167. // 下拉刷新
  168. // const refreshing = ref(false);
  169. const user = getLoginUser();
  170. const companyTypeShow = ref(false);
  171. // 是否管理员
  172. const isAdmin = () => { return (user && user.type === 0); }
  173. // 公司平台弹窗
  174. const companyTypeInpClk = () => {
  175. companyTypeShow.value = true;
  176. };
  177. onMounted(() => {
  178. // 加载样式
  179. styleUrl('orderExport');
  180. // ruleData.tableData = [];
  181. tableData.value = [];
  182. pageNo.value = 1;
  183. pageSize.value = 10;
  184. // 今日
  185. searchParams.startDate = moment().format("YYYY-MM-DD") + " 00:00:00";
  186. searchParams.endDate = moment().format("YYYY-MM-DD") + " 23:59:59";
  187. if (user) {
  188. // onRefresh();
  189. finished.value = false;
  190. getList();
  191. }
  192. });
  193. // 下拉刷新
  194. // const onRefresh = (idx) => {
  195. // ruleData.tableData = [];
  196. // // 解决请求两次问题
  197. // if (!idx) {
  198. // finished.value = false;
  199. // }
  200. // loading.value = true;
  201. // // 初始化分页
  202. // pageNo.value = 1;
  203. // pageSize.value = 10;
  204. // getList();
  205. // };
  206. // 上拉加载
  207. const onLoad = () => {
  208. // if (!finished.value) {
  209. if (!finished.value) {
  210. pageNo.value = pageNo.value + pageSize.value;
  211. getList();
  212. }
  213. };
  214. // 获取列表数据
  215. const getList = async () => {
  216. loading.value = true;
  217. finished.value = false;
  218. // 如果存在chartType去掉
  219. if (searchParams.chartType) {
  220. delete searchParams.chartType;
  221. }
  222. let param = {
  223. current: pageNo.value,
  224. size: pageSize.value,
  225. };
  226. const { data } = await getOrderList(Object.assign(param, searchParams));
  227. if (data.code === "00000") {
  228. if (data.data.total === 0) {
  229. finished.value = true;
  230. } else {
  231. if (param.current === 1) {
  232. tableData.value = [];
  233. orderTotal.value = 0;
  234. }
  235. // 列表值叠加
  236. if (data.data.records.length > 0) {
  237. tableData.value = tableData.value.concat(data.data.records);
  238. orderTotal.value = data.data.records.length + orderTotal.value;
  239. if (orderTotal.value === data.data.total) {
  240. finished.value = true;
  241. }
  242. } else {
  243. finished.value = true;
  244. }
  245. }
  246. loading.value = false;
  247. } else {
  248. loading.value = false;
  249. showFailToast("数据加载失败");
  250. }
  251. };
  252. // getOrderList(Object.assign(param, searchParams)).then((res) => {
  253. // const { data } = res.data;
  254. // console.log('data的值是 >>>', data)
  255. // if (data) {
  256. // // refreshing.value = false;
  257. // ruleData.tableData.push(...data.records);
  258. // console.log("数据长度:", ruleData.tableData.length);
  259. // console.log("数据量:", data.total);
  260. // // 加载状态结束
  261. // loading.value = false;
  262. // if (ruleData.tableData.length === data.total) {
  263. // finished.value = true;
  264. // }
  265. // }
  266. // });
  267. // };
  268. // 引入语言
  269. const { t } = useI18n();
  270. // 大陆或海外弹窗
  271. // 控制显示
  272. const changeTypeShow = ref(false);
  273. // 点击显示弹窗
  274. const changeTypeInpClk = () => {
  275. changeTypeShow.value = true;
  276. };
  277. // 弹窗选中的值
  278. const changeTypePopFieldName = reactive({
  279. text: "name",
  280. value: "id",
  281. });
  282. // 弹窗选项
  283. const changeTypePopList = [
  284. {
  285. name: t('orderExport.searchPop.mainland'),
  286. id: "0",
  287. },
  288. {
  289. name: t('orderExport.searchPop.overseas'),
  290. id: "1",
  291. },
  292. ];
  293. // 点击弹窗的确定按钮
  294. const changeTypePopConfirm = ({ selectedOptions }) => {
  295. searchForm.ifForeign = selectedOptions[0].id;
  296. searchForm.ifForeignName = selectedOptions[0].name;
  297. changeTypeShow.value = false;
  298. };
  299. const companyTypePopConfirm = ({ selectedOptions }) => {
  300. searchForm.companyType = selectedOptions[0].id;
  301. searchForm.companyTypeName = selectedOptions[0].name;
  302. companyTypeShow.value = false;
  303. };
  304. // 点击导出按钮
  305. const exportOrder = async () => {
  306. const param = {
  307. current: pageNo.value,
  308. size: pageSize.value,
  309. };
  310. const { headers, data } = await Api_getOrderExport(Object.assign(param, searchParams));
  311. // console.log('headers', headers)
  312. // console.log('data', data)
  313. $M_ExportFile(data, headers);
  314. };
  315. // 筛选弹窗的元素
  316. const kDialogRef = ref(null);
  317. // 点击筛选
  318. const noticeClk = () => {
  319. kDialogRef.value.openDialog();
  320. };
  321. // 筛选弹窗
  322. const searchForm = reactive({
  323. orderNo: "",
  324. busiName: "",
  325. ifForeign: "0",
  326. ifForeignName: "大陆",
  327. companyType: "",
  328. companyTypeName: "全部",
  329. });
  330. // 点击筛选条件的清空条件按钮
  331. const cancelClk = () => {
  332. searchForm.orderNo = '';
  333. searchForm.busiName = '';
  334. searchForm.ifForeign = '0';
  335. searchForm.ifForeignName = '大陆';
  336. searchForm.companyType = "";
  337. };
  338. // 点击筛选条件的筛选按钮
  339. const confirmClk = () => {
  340. searchParams.clientId = searchForm.orderNo;
  341. searchParams.username = searchForm.busiName;
  342. searchParams.ifForeign = searchForm.ifForeign;
  343. searchParams.companyType = searchForm.companyType;
  344. tableData.value = [];
  345. getList();
  346. };
  347. // 商户设备tab栏
  348. const tabList = ref([
  349. {
  350. name: t("orderExport.merchant"),
  351. icon: "",
  352. id: 1,
  353. },
  354. {
  355. name: t("orderExport.equipment"),
  356. icon: "",
  357. id: 2,
  358. },
  359. ]);
  360. // 公司平台
  361. const companyTypePopList = [
  362. {
  363. name: t("orderExport.searchPop.whole"),
  364. id: "",
  365. },
  366. {
  367. name: t("orderExport.searchPop.sz"),
  368. id: "0",
  369. },
  370. {
  371. name: t("orderExport.searchPop.sc"),
  372. id: "1",
  373. },
  374. ];
  375. // 点击tab
  376. const tabChg = (e) => {
  377. pageNo.value = 1;
  378. pageSize.value = 10;
  379. // ruleData.tableData = [];
  380. tableData.value = [];
  381. if (e == 1) {
  382. searchParams.type = 1;
  383. } else {
  384. searchParams.type = 2;
  385. }
  386. getList();
  387. };
  388. let searchParams = reactive({
  389. type: "2", // 分组类型
  390. clientId: "", // 设备编号
  391. username: "",
  392. startDate: "",
  393. endDate: "",
  394. ifForeign: '0',
  395. adminId: user.id,
  396. companyType: "",
  397. });
  398. // 搜索点击
  399. const searchClick = () => {
  400. // console.log("searchClick");
  401. };
  402. // 今日、明日、本周、本月、其他时间选择回调
  403. const update = (uDate) => {
  404. pageNo.value = 1;
  405. pageSize.value = 10;
  406. // ruleData.tableData = [];
  407. tableData.value = [];
  408. searchParams = Object.assign(searchParams, uDate);
  409. searchParams.startDate = dateUtil.formateDate(
  410. new Date(searchParams.startDate),
  411. "yyyy-MM-dd hh:mm:ss"
  412. );
  413. searchParams.endDate = dateUtil.formateDate(
  414. new Date(searchParams.endDate),
  415. "yyyy-MM-dd hh:mm:ss"
  416. );
  417. getList();
  418. // onRefresh(1);
  419. };
  420. // 自定义货币符号
  421. const currencySymbol = ref('¥');
  422. const loginUserStr = localStorage.getItem('loginUser');
  423. const loginUser = JSON.parse(loginUserStr);
  424. if (loginUser.currencySymbol) {
  425. currencySymbol.value = loginUser.currencySymbol;
  426. } else {
  427. currencySymbol.value = '¥';
  428. }
  429. return {
  430. ...toRefs(searchParams),
  431. companyTypePopConfirm,
  432. companyTypePopList,
  433. searchClick,
  434. companyTypeInpClk,
  435. companyTypeShow,
  436. update,
  437. exportOrder,
  438. tabChg,
  439. tabList,
  440. confirmClk,
  441. searchForm,
  442. noticeClk,
  443. kDialogRef,
  444. cancelClk,
  445. changeTypePopList,
  446. changeTypePopConfirm,
  447. changeTypeShow,
  448. changeTypeInpClk,
  449. changeTypePopFieldName,
  450. pageNo,
  451. pageSize,
  452. loading,
  453. finished,
  454. // refreshing,
  455. // onRefresh,
  456. onLoad,
  457. getList,
  458. isAdmin,
  459. tableData,
  460. error,
  461. // ...toRefs(ruleData),
  462. currencySymbol,
  463. };
  464. },
  465. };
  466. </script>
  467. <style lang="less" scoped>
  468. @import "../../common/style/common.less";
  469. @import "../../styles/orderExport/index.less";
  470. </style>