金币系统前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

772 lines
20 KiB

  1. <script setup>
  2. import { ref, onMounted, reactive, computed } from "vue";
  3. import ElementPlus from "element-plus";
  4. import { ElMessage, ElMessageBox } from "element-plus";
  5. import axios from "axios";
  6. import moment from "moment";
  7. import { ta } from "element-plus/es/locales.mjs";
  8. import API from "../../api/index.js";
  9. import * as XLSX from "xlsx";
  10. // 变量
  11. //这是获取用户信息的接口
  12. const adminData = ref({});
  13. const getAdminData = async function () {
  14. try {
  15. const result = await API.post(
  16. "http://54.251.137.151:10702/admin/userinfo",
  17. {}
  18. );
  19. adminData.value = result;
  20. console.log("请求成功", result);
  21. console.log("用户信息", adminData.value);
  22. } catch (error) {
  23. console.log("请求失败", error);
  24. }
  25. };
  26. // 充值明细表格
  27. const tableData = ref([]);
  28. // 计算用户各金币总数的不分页对象
  29. const tableAllData = ref([]);
  30. // 各金币总数
  31. const rechargeCoin = ref(0);
  32. const freeCoin = ref(0);
  33. const taskCoin = ref(0);
  34. // 搜索===========================================
  35. //分页总条目
  36. const total = ref(100);
  37. // 搜索对象时间
  38. const getTime = ref([]);
  39. // 搜索detailY
  40. const detailY = ref({});
  41. // 不分页的搜索对象
  42. const getAllObj = ref({});
  43. // 搜索对象
  44. const getObj = ref({
  45. pageNum: 1,
  46. pageSize: 50,
  47. });
  48. //开启条件筛选导出excel
  49. const getPutEX = ref(false);
  50. // 支付方式选项
  51. const updateType = [
  52. {
  53. value: "0",
  54. label: "充值",
  55. },
  56. {
  57. value: "1",
  58. label: "消费",
  59. },
  60. {
  61. value: "2",
  62. label: "退款",
  63. },
  64. {
  65. value: "3",
  66. label: "其他",
  67. },
  68. ];
  69. // //表格高度
  70. // const tableHeight = computed(function () {
  71. // return (getObj.value.pageSize + 2) * 38 + "px";
  72. // });
  73. // 方法
  74. // 搜索===========================================================================
  75. // 搜索方法
  76. const get = async function (val) {
  77. try {
  78. // 地区赋值
  79. if (adminData.value.area != "总部") {
  80. detailY.value.area = adminData.value.area;
  81. }
  82. // 搜索参数页码赋值
  83. if (typeof val === "number") {
  84. getObj.value.pageNum = val;
  85. }
  86. // 搜索参数时间赋值
  87. if (getTime.value != null) {
  88. if (getTime.value.startDate != "" && getTime.value.endDate != "") {
  89. detailY.value.startDate = getTime.value[0];
  90. detailY.value.endDate = getTime.value[1];
  91. }
  92. } else {
  93. detailY.value.startDate = "";
  94. detailY.value.endDate = "";
  95. }
  96. console.log("搜索参数", getObj.value);
  97. // 发送POST请求
  98. const result = await API.post("http://54.251.137.151:10702/detailY", {
  99. ...getObj.value,
  100. detailY: { ...detailY.value },
  101. });
  102. const result2 = await API.post("http://54.251.137.151:10702/detailY", {
  103. ...getAllObj.value,
  104. detailY: { ...detailY.value },
  105. });
  106. // 将响应结果存储到响应式数据中
  107. console.log("请求成功", result);
  108. console.log("请求成功2", result2);
  109. // 存储表格数据
  110. tableData.value = result.data.list;
  111. console.log("tableData", tableData.value);
  112. tableAllData.value = result2.data;
  113. console.log("tableAllData", tableAllData.value);
  114. // 存储分页总数
  115. total.value = result.data.total;
  116. console.log("total", total.value);
  117. // 计算各金币总数并除以100
  118. // 下列各数除以100
  119. rechargeCoin.value = tableAllData.value.sumR / 100;
  120. freeCoin.value = tableAllData.value.sumF / 100;
  121. taskCoin.value = tableAllData.value.sumT / 100;
  122. // for (let i = 0; i < tableAllData.value.length; i++) {
  123. // rechargeCoin.value += tableAllData.value[i].rechargeCoin;
  124. // freeCoin.value += tableAllData.value[i].freeCoin;
  125. // taskCoin.value += tableAllData.value[i].taskCoin;
  126. // }
  127. console.log(
  128. "各金币总数",
  129. rechargeCoin.value,
  130. freeCoin.value,
  131. taskCoin.value
  132. );
  133. } catch (error) {
  134. console.log("请求失败", error);
  135. // 在这里可以处理错误逻辑,比如显示错误提示等
  136. }
  137. };
  138. // 搜索
  139. const search = function () {
  140. getObj.value.pageNum = 1;
  141. get();
  142. };
  143. // 重置
  144. const reset = function () {
  145. detailY.value.jwcode = "";
  146. detailY.value.updateType = "";
  147. detailY.value.startDate = "";
  148. detailY.value.endDate = "";
  149. getTime.value = {};
  150. };
  151. // 今天
  152. const getToday = function () {
  153. const today = new Date();
  154. const startDate = new Date(
  155. today.getFullYear(),
  156. today.getMonth(),
  157. today.getDate()
  158. );
  159. const endDate = new Date(
  160. today.getFullYear(),
  161. today.getMonth(),
  162. today.getDate() + 1
  163. );
  164. getTime.value = [startDate, endDate];
  165. console.log("getTime", getTime.value);
  166. get();
  167. };
  168. // 昨天
  169. const getYesterday = function () {
  170. const yesterday = new Date();
  171. yesterday.setDate(yesterday.getDate() - 1);
  172. const startDate = new Date(
  173. yesterday.getFullYear(),
  174. yesterday.getMonth(),
  175. yesterday.getDate()
  176. );
  177. const endDate = new Date(
  178. yesterday.getFullYear(),
  179. yesterday.getMonth(),
  180. yesterday.getDate() + 1
  181. );
  182. getTime.value = [startDate, endDate];
  183. console.log("getTime", getTime.value);
  184. get();
  185. };
  186. // 近7天
  187. const get7Days = function () {
  188. const today = new Date();
  189. const startDate = new Date(
  190. today.getFullYear(),
  191. today.getMonth(),
  192. today.getDate() - 6
  193. );
  194. const endDate = new Date(
  195. today.getFullYear(),
  196. today.getMonth(),
  197. today.getDate() + 1
  198. );
  199. getTime.value = [startDate, endDate];
  200. console.log("getTime", getTime.value);
  201. get();
  202. };
  203. // 验证跳转输入框的数字是否合法
  204. const checkNumber = function () {
  205. if (typeof parseInt(getObj.value.pageNum) === "number") {
  206. console.log(
  207. "总共有多少页" + Math.ceil(total.value / getObj.value.pageSize)
  208. );
  209. if (
  210. getObj.value.pageNum > 0 &&
  211. getObj.value.pageNum <= Math.ceil(total.value / getObj.value.pageSize)
  212. ) {
  213. getObj.value.pageNum = parseInt(getObj.value.pageNum);
  214. console.log("输入的数字合法");
  215. get();
  216. } else {
  217. //提示
  218. ElMessage({
  219. type: "error",
  220. message: "请检查输入内容",
  221. });
  222. }
  223. } else {
  224. //提示
  225. ElMessage({
  226. type: "error",
  227. message: "请检查输入内容",
  228. });
  229. }
  230. };
  231. // 挂载
  232. onMounted(async function () {
  233. await getAdminData();
  234. await get();
  235. });
  236. // 这是导出excel表格的方法
  237. // 导出Excel的方法
  238. // 定义字段映射
  239. const json_fields = (row) => {
  240. return [
  241. row.jwcode, // 姓名
  242. row.area, // 精网号
  243. row.platform, // 所属地区
  244. row.count, // 平台信息
  245. row.updateType, // 更新数量
  246. row.rechargeCoin, // 免费金币
  247. row.freeCoin, // 永久金币
  248. row.taskCoin, // 任务金币
  249. row.createAdmin, // 提交人
  250. row.createTime,
  251. row.name,
  252. row.id,
  253. ];
  254. };
  255. // 定义元数据
  256. const json_meta = [
  257. [
  258. {
  259. key: "charset",
  260. value: "utf-8",
  261. },
  262. ],
  263. ];
  264. const headers = [
  265. "精网号",
  266. "地区",
  267. "平台信息",
  268. "数量",
  269. "更新类型",
  270. "永久金币",
  271. "免费金币",
  272. "任务金币",
  273. "提交人",
  274. "更新时间",
  275. "用户名",
  276. "id",
  277. ];
  278. const exportExcel = () => {
  279. // 先将 json_fields 应用到数据上
  280. const data = excelInfo.value.map(json_fields);
  281. const ws = XLSX.utils.aoa_to_sheet(data);
  282. // 添加表头到工作表
  283. XLSX.utils.sheet_add_aoa(ws, [headers], { origin: "A1" });
  284. const wb = XLSX.utils.book_new();
  285. XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
  286. XLSX.writeFile(wb, "客户金币明细.xlsx");
  287. };
  288. const today = new Date();
  289. const startDate = new Date(
  290. today.getFullYear(),
  291. today.getMonth(),
  292. today.getDate()
  293. );
  294. const endDate = new Date(
  295. today.getFullYear(),
  296. today.getMonth(),
  297. today.getDate() + 1
  298. );
  299. const putExcel = ref({
  300. startDate: startDate,
  301. endDate: endDate,
  302. });
  303. const excelInfo = ref({});
  304. const loading = ref(false);
  305. const areyour = async function () {
  306. try {
  307. loading.value = true;
  308. const result = await API.post(
  309. "http://54.251.137.151:10702/detailY/searchAll",
  310. {
  311. ...putExcel.value,
  312. }
  313. );
  314. excelInfo.value = result.data;
  315. // 处理 excelInfo 中的数据
  316. if (Array.isArray(excelInfo.value)) {
  317. excelInfo.value.forEach((item) => {
  318. if (item.rechargeCoin) {
  319. item.rechargeCoin = item.rechargeCoin / 100;
  320. }
  321. if (item.freeCoin) {
  322. item.freeCoin = item.freeCoin / 100;
  323. }
  324. if (item.taskCoin) {
  325. item.taskCoin = item.taskCoin / 100;
  326. }
  327. });
  328. }
  329. areyouright.value = true;
  330. ElMessage({
  331. type: "success",
  332. message: "查询成功",
  333. });
  334. loading.value = false;
  335. } catch (error) {
  336. console.log("请求失败", error);
  337. loading.value = false;
  338. }
  339. };
  340. const areyouright = ref(false);
  341. //选地区
  342. const area = [
  343. {
  344. value: "马来西亚",
  345. label: "马来西亚",
  346. },
  347. {
  348. value: "新加坡",
  349. label: "新加坡",
  350. },
  351. {
  352. value: "香港",
  353. label: "香港",
  354. },
  355. {
  356. value: "泰国",
  357. label: "泰国",
  358. },
  359. {
  360. value: "加拿大",
  361. label: "加拿大",
  362. },
  363. {
  364. value: "越南HCM",
  365. label: "越南HCM",
  366. },
  367. ];
  368. //选消费平台
  369. const platform = [
  370. {
  371. value: "金币系统",
  372. label: "金币系统",
  373. },
  374. {
  375. value: "ERP系统",
  376. label: "ERP系统",
  377. },
  378. ];
  379. const TimeGet = ref("1");
  380. // 今天
  381. const getT = function () {
  382. const today = new Date();
  383. const startDate = new Date(
  384. today.getFullYear(),
  385. today.getMonth(),
  386. today.getDate()
  387. );
  388. const endDate = new Date(
  389. today.getFullYear(),
  390. today.getMonth(),
  391. today.getDate() + 1
  392. );
  393. putExcel.value.startDate = startDate;
  394. putExcel.value.endDate = endDate;
  395. console.log("putExcel", putExcel.value);
  396. };
  397. //3天
  398. const get3 = function () {
  399. const today = new Date();
  400. const startDate = new Date(
  401. today.getFullYear(),
  402. today.getMonth(),
  403. today.getDate() - 2
  404. );
  405. const endDate = new Date(
  406. today.getFullYear(),
  407. today.getMonth(),
  408. today.getDate() + 1
  409. );
  410. putExcel.value.startDate = startDate;
  411. putExcel.value.endDate = endDate;
  412. console.log("putExcel", putExcel.value);
  413. };
  414. // 7天
  415. const get7 = function () {
  416. const today = new Date();
  417. const startDate = new Date(
  418. today.getFullYear(),
  419. today.getMonth(),
  420. today.getDate() - 6
  421. );
  422. const endDate = new Date(
  423. today.getFullYear(),
  424. today.getMonth(),
  425. today.getDate() + 1
  426. );
  427. putExcel.value.startDate = startDate;
  428. putExcel.value.endDate = endDate;
  429. console.log("putExcel", putExcel.value);
  430. };
  431. // 30天
  432. const get30 = function () {
  433. const today = new Date();
  434. const startDate = new Date(
  435. today.getFullYear(),
  436. today.getMonth() - 1,
  437. today.getDate()
  438. );
  439. const endDate = new Date(
  440. today.getFullYear(),
  441. today.getMonth(),
  442. today.getDate() + 1
  443. );
  444. putExcel.value.startDate = startDate;
  445. putExcel.value.endDate = endDate;
  446. console.log("putExcel", putExcel.value);
  447. };
  448. </script>
  449. <template>
  450. <el-dialog
  451. v-model="areyouright"
  452. title=""
  453. width="500"
  454. :close-on-click-modal="false"
  455. >
  456. <el-button type="success" @click="exportExcel()">导出</el-button>
  457. </el-dialog>
  458. <!-- 这是导出excel的弹窗 -->
  459. <el-dialog
  460. v-model="getPutEX"
  461. title="请选择导出条件"
  462. width="500"
  463. :close-on-click-modal="false"
  464. >
  465. <template #footer>
  466. <el-form
  467. v-loading="loading"
  468. ref="ruleFormRef"
  469. style="max-width: 600px"
  470. :model="putExcel"
  471. :rules="rules"
  472. label-width="auto"
  473. class="demo-ruleForm"
  474. :size="formSize"
  475. status-icon
  476. >
  477. <el-form-item prop="activityName" label="精网号:">
  478. <el-input
  479. v-model="putExcel.jwcode"
  480. placeholder="请输入精网号"
  481. style="width: 220px"
  482. />
  483. </el-form-item>
  484. <el-form-item label="所属地区:"
  485. ><el-select
  486. v-model="putExcel.area"
  487. placeholder="请选择所属地区"
  488. style="width: 240px"
  489. clearable
  490. >
  491. <el-option
  492. v-for="item in area"
  493. :key="item.value"
  494. :label="item.label"
  495. :value="item.value"
  496. />
  497. </el-select>
  498. </el-form-item>
  499. <el-form-item label="更新时间:">
  500. <el-radio-group v-model="TimeGet">
  501. <el-radio value="1" @click="getT()">今天</el-radio>
  502. <el-radio value="3" @click="get3()">近三天</el-radio>
  503. <el-radio value="7" @click="get7()">近一周</el-radio>
  504. <el-radio value="30" @click="get30()">近一个月</el-radio>
  505. </el-radio-group>
  506. </el-form-item>
  507. <el-button
  508. type="primary"
  509. size="small"
  510. style="margin-left: 10px"
  511. @click="areyour()"
  512. >确定</el-button
  513. >
  514. </el-form>
  515. </template>
  516. </el-dialog>
  517. <el-row>
  518. <el-col>
  519. <el-card style="margin-bottom: 20px">
  520. <el-row style="margin-bottom: 10px">
  521. <el-col :span="8">
  522. <div class="head-card-element">
  523. <el-text class="mx-1" size="large">精网号</el-text>
  524. <el-input
  525. v-model="detailY.jwcode"
  526. style="width: 240px"
  527. placeholder="请输入精网号"
  528. clearable
  529. />
  530. </div>
  531. </el-col>
  532. <el-col :span="8">
  533. <div class="head-card-element">
  534. <el-text class="mx-1" size="large">平台信息</el-text>
  535. <el-select
  536. v-model="detailY.plateform"
  537. placeholder="请选择平台信息"
  538. style="width: 200px"
  539. clearable
  540. >
  541. <el-option
  542. v-for="item in platform"
  543. :key="item.value"
  544. :label="item.label"
  545. :value="item.value"
  546. />
  547. </el-select>
  548. </div>
  549. </el-col>
  550. <el-col :span="8">
  551. <div class="head-card-element">
  552. <el-text class="mx-1" size="large">更新类型</el-text>
  553. <el-select
  554. v-model="detailY.updateType"
  555. placeholder="请选择更新类型"
  556. style="width: 200px"
  557. clearable
  558. >
  559. <el-option
  560. v-for="item in updateType"
  561. :key="item.value"
  562. :label="item.label"
  563. :value="item.value"
  564. />
  565. </el-select>
  566. </div>
  567. </el-col>
  568. </el-row>
  569. <div class="head-card-element">
  570. <el-text class="mx-1" size="large">更新时间</el-text>
  571. <el-date-picker
  572. v-model="getTime"
  573. type="datetimerange"
  574. range-separator="至"
  575. start-placeholder="起始时间"
  576. end-placeholder="结束时间"
  577. style="margin-right: 700px"
  578. />
  579. <el-button type="success" @click="getPutEX = true"
  580. >导出Excel表格</el-button
  581. >
  582. <el-button @click="reset()">重置</el-button>
  583. <el-button type="primary" @click="search()">查询</el-button>
  584. </div>
  585. </el-card>
  586. </el-col>
  587. </el-row>
  588. <el-row>
  589. <el-col>
  590. <el-card>
  591. <div>
  592. 现有金币免费金币{{ Math.abs(freeCoin) }}永久金币{{
  593. Math.abs(rechargeCoin)
  594. }}任务金币{{ Math.abs(taskCoin) }}
  595. </div>
  596. <!-- 设置表格容器的高度和滚动样式 -->
  597. <div style="height: 670px; overflow-y: auto">
  598. <el-table :data="tableData" style="width: 100%" height="670px">
  599. <el-table-column
  600. type="index"
  601. label="序号"
  602. width="100px"
  603. fixed="left"
  604. >
  605. <template #default="scope">
  606. <span>{{
  607. scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
  608. }}</span>
  609. </template>
  610. </el-table-column>
  611. <el-table-column
  612. fixed="left"
  613. prop="username"
  614. label="姓名"
  615. width="130"
  616. />
  617. <el-table-column
  618. fixed="left"
  619. prop="jwcode"
  620. label="精网号"
  621. width="170"
  622. />
  623. <el-table-column prop="area" label="所属地区" width="170" />
  624. <el-table-column
  625. prop="consumePlatform"
  626. label="平台信息"
  627. width="170"
  628. />
  629. <el-table-column prop="gold" label="更新数量" width="160">
  630. <template #default="scope">
  631. <span>{{
  632. Math.abs(
  633. scope.row.rechargeCoin +
  634. scope.row.freeCoin +
  635. scope.row.taskCoin
  636. ) / 100
  637. }}</span>
  638. </template>
  639. </el-table-column>
  640. <el-table-column prop="updateType" label="更新类型" width="150">
  641. <!-- 模板内容 -->
  642. <template #default="scope">
  643. <span v-if="scope.row.updateType == 1">
  644. <span>消费</span>
  645. </span>
  646. <span v-if="scope.row.updateType == 0">
  647. <span>充值</span>
  648. </span>
  649. <span v-if="scope.row.updateType == 2">
  650. <span>退款</span>
  651. </span>
  652. <span v-if="scope.row.updateType == 3">
  653. <span>其他</span>
  654. </span>
  655. </template>
  656. </el-table-column>
  657. <el-table-column prop="freeCoin" label="免费金币" width="130">
  658. <template #default="scope">
  659. <span>{{ scope.row.freeCoin / 100 }}</span>
  660. </template>
  661. </el-table-column>
  662. <el-table-column prop="rechargeCoin" label="永久金币" width="150">
  663. <template #default="scope">
  664. <span>{{ scope.row.rechargeCoin / 100 }}</span>
  665. </template>
  666. </el-table-column>
  667. <el-table-column prop="taskCoin" label="任务金币" width="130">
  668. <template #default="scope">
  669. <span>{{ scope.row.taskCoin / 100 }}</span>
  670. </template>
  671. </el-table-column>
  672. <el-table-column prop="name" label="提交人" width="150" />
  673. <el-table-column
  674. prop="createTime"
  675. label="更新时间"
  676. width="210"
  677. show-overflow-tooltip
  678. >
  679. <template #default="scope">
  680. <span>{{
  681. moment(scope.row.createTime).format("YYYY-MM-DD HH:mm:ss")
  682. }}</span>
  683. </template>
  684. </el-table-column>
  685. </el-table>
  686. </div>
  687. <!-- 分页 -->
  688. <!-- 分页 -->
  689. <div class="pagination" style="margin-top: 20px">
  690. <el-pagination
  691. background
  692. :page-size="getObj.pageSize"
  693. layout="slot"
  694. :total="total"
  695. >
  696. <div>{{ total }},每页</div>
  697. <el-select
  698. v-model="getObj.pageSize"
  699. class="page-size"
  700. @change="get()"
  701. style="width: 80px"
  702. >
  703. <el-option
  704. v-for="item in [5, 10, 20, 50, 100]"
  705. :key="item"
  706. :label="item"
  707. :value="item"
  708. ></el-option>
  709. </el-select>
  710. <div></div>
  711. </el-pagination>
  712. <el-pagination
  713. background
  714. layout="prev, pager, next,slot"
  715. :page-size="getObj.pageSize"
  716. :total="total"
  717. :current-page="getObj.pageNum"
  718. @current-change="get"
  719. >
  720. <div>跳至</div>
  721. <el-input
  722. v-model="getObj.pageNum"
  723. style="width: 40px"
  724. @change="checkNumber"
  725. />
  726. <div></div>
  727. </el-pagination>
  728. </div>
  729. </el-card>
  730. </el-col>
  731. </el-row>
  732. </template>
  733. <style scoped>
  734. .pagination {
  735. display: flex;
  736. }
  737. .status {
  738. display: flex;
  739. }
  740. .head-card {
  741. display: flex;
  742. }
  743. /* .head-card-element {
  744. margin-right: 20px;
  745. } */
  746. /* .head-card-btn {
  747. margin-left: auto;
  748. } */
  749. </style>