金币系统前端
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.

798 lines
22 KiB

4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
  1. <script setup>
  2. import { ref, onMounted, computed, reactive } from "vue";
  3. import { ElMessage, ElMessageBox } from "element-plus";
  4. import axios from "axios";
  5. import { createApp } from "vue";
  6. import moment from "moment";
  7. import API from "../../api/index.js";
  8. import _ from "lodash";
  9. // 查询用户接口
  10. const adminData = ref({
  11. name: "",
  12. });
  13. const getAdminData = async function () {
  14. try {
  15. const result = await API.post(
  16. "http://39.99.159.73:20090/admin/userinfo",
  17. {}
  18. );
  19. adminData.value = result;
  20. rateAdd.value.adminId = adminData.value.adminId;
  21. rateEdit.value.adminId = adminData.value.adminId;
  22. console.log("请求成功", result);
  23. console.log("用户信息", user.value);
  24. } catch (error) {
  25. console.log("请求失败", error);
  26. }
  27. };
  28. getAdminData();
  29. const regeAdd = ref(false);
  30. const regeEdit = ref(false);
  31. //汇率表格数据
  32. const tableData = ref([]);
  33. //搜索对象
  34. const getObj = ref({
  35. pageNum: 1,
  36. pageSize: 10,
  37. });
  38. const total = ref(0);
  39. //分页总条目
  40. //时间选择器
  41. const value1 = ref({
  42. startTime: "",
  43. endTime: "",
  44. }); // 时间数组
  45. function handleDateChange(value) {
  46. if (value && value.length === 2) {
  47. value1.value.startTime = value[0]; // 开始日期
  48. value1.value.endTime = value[1]; // 结束日期
  49. }
  50. console.log(value1);
  51. }
  52. const time = ref({});
  53. const get = async function (val) {
  54. // 搜索参数时间赋值
  55. if (value1.value != null) {
  56. if (value1.value.startDate != "" && value1.value.endDate != "") {
  57. time.value.startTime = value1.value[0];
  58. time.value.endTime = value1.value[1];
  59. }
  60. } else {
  61. time.value.startTime = "";
  62. time.value.endTime = "";
  63. }
  64. try {
  65. // 搜索参数页码赋值
  66. if (typeof val === "number") {
  67. getObj.value.pageNum = val;
  68. }
  69. console.log("搜索参数", getObj.value);
  70. // 发送POST请求
  71. const result = await API.post("http://39.99.159.73:20090/rates/search", {
  72. ...getObj.value,
  73. rate: { ...time.value },
  74. });
  75. // 将响应结果存储到响应式数据中
  76. console.log("请求成功", result);
  77. // 存储表格数据
  78. tableData.value = result.data.list;
  79. console.log("tableData", tableData.value);
  80. // 在这里可以根据需求进一步处理成功后的逻辑,比如更新UI显示成功消息等
  81. // 存储分页总条目
  82. total.value = result.data.total;
  83. console.log("total", total.value);
  84. } catch (error) {
  85. console.log("请求失败", error);
  86. // 在这里可以处理错误逻辑,比如显示错误提示等
  87. }
  88. };
  89. // 搜索
  90. const search = function () {
  91. getObj.value.pageNum = 1;
  92. get();
  93. };
  94. // 添加方法
  95. const rateAdd = ref({});
  96. const addRate = async function () {
  97. rateAdd.value.adminId = adminData.value.adminId;
  98. if (rateAdd.value.startTime) {
  99. const date = new Date(rateAdd.value.startTime);
  100. date.setHours(0, 0, 0, 0);
  101. rateAdd.value.startTime = `${date.getFullYear()}-${String(
  102. date.getMonth() + 1
  103. ).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")} 00:00:00`;
  104. }
  105. if (rateAdd.value.endTime) {
  106. const date = new Date(rateAdd.value.endTime);
  107. date.setHours(23, 59, 59, 999);
  108. rateAdd.value.endTime = `${date.getFullYear()}-${String(
  109. date.getMonth() + 1
  110. ).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")} 23:59:59`;
  111. }
  112. try {
  113. console.log("搜索参数", getObj.value);
  114. // 发送POST请求
  115. const result = await API.post(
  116. "http://39.99.159.73:20090/rates/add",
  117. rateAdd.value
  118. );
  119. if (result.code == 0) {
  120. ElMessage.error(result.msg);
  121. }
  122. // 将响应结果存储到响应式数据中
  123. console.log("请求成功", result);
  124. get();
  125. } catch (error) {
  126. console.log("请求失败", error);
  127. // 在这里可以处理错误逻辑,比如显示错误提示等
  128. }
  129. };
  130. const add = () => {
  131. Ref.value.validate(async (valid) => {
  132. if (valid) {
  133. ElMessageBox.confirm("确认添加?")
  134. .then(() => {
  135. addRate();
  136. rateAdd.value = {};
  137. value1.value = {
  138. startTime: "",
  139. endTime: "",
  140. };
  141. regeAdd.value = false;
  142. })
  143. .catch(() => {
  144. regeAdd.value = false;
  145. });
  146. } else {
  147. //提示
  148. ElMessage({
  149. type: "error",
  150. message: "请检查输入内容",
  151. });
  152. }
  153. });
  154. };
  155. // 使用 _.throttle 并设置 trailing 为 false 实现严格节流,只执行一次
  156. const throttledAdd = _.throttle(add, 5000, { trailing: false });
  157. // 编辑方法
  158. const rateEdit = ref({});
  159. //查询已有的数据
  160. const getEditData = async function (row) {
  161. try {
  162. console.log("搜索参数", getObj.value);
  163. // 发送POST请求
  164. const result = await API.post(
  165. "http://39.99.159.73:20090/rates/searchById?rateId=" + row.rateId,
  166. {}
  167. );
  168. // 将响应结果存储到响应式数据中
  169. console.log("请求成功", result);
  170. // 存储表格数据
  171. rateEdit.value = result.data;
  172. rateEdit.value.adminId = adminData.value.adminId;
  173. console.log("这是编辑的数值", rateEdit.value);
  174. } catch (error) {
  175. console.log("请求失败", error);
  176. // 在这里可以处理错误逻辑,比如显示错误提示等
  177. }
  178. };
  179. const editRate = async function () {
  180. if (rateEdit.value.startTime) {
  181. const date = new Date(rateEdit.value.startTime);
  182. date.setHours(0, 0, 0, 0);
  183. rateEdit.value.startTime = `${date.getFullYear()}-${String(
  184. date.getMonth() + 1
  185. ).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")} 00:00:00`;
  186. }
  187. if (rateEdit.value.endTime) {
  188. const date = new Date(rateEdit.value.endTime);
  189. date.setHours(23, 59, 59, 999);
  190. rateEdit.value.endTime = `${date.getFullYear()}-${String(
  191. date.getMonth() + 1
  192. ).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")} 23:59:59`;
  193. }
  194. try {
  195. console.log("搜索参数", rateEdit.value);
  196. // 发送POST请求
  197. const result = await API.post(
  198. "http://39.99.159.73:20090/rates/update",
  199. rateEdit.value
  200. );
  201. // 将响应结果存储到响应式数据中
  202. console.log("请求成功", result);
  203. get();
  204. } catch (error) {
  205. console.log("请求失败", error);
  206. // 在这里可以处理错误逻辑,比如显示错误提示等
  207. }
  208. };
  209. const edit = () => {
  210. ElMessageBox.confirm("确认修改?")
  211. .then(() => {
  212. editRate();
  213. regeEdit.value = false;
  214. })
  215. .catch(() => {
  216. regeEdit.value = false;
  217. });
  218. };
  219. // 删除方法
  220. const deleteRate = async function (row) {
  221. try {
  222. // 发送POST请求
  223. const result = await API.post(
  224. "http://39.99.159.73:20090/rates/delete/ " + row.rateId,
  225. {}
  226. );
  227. // 将响应结果存储到响应式数据中
  228. console.log("请求成功", result);
  229. get();
  230. } catch (error) {
  231. console.log("请求失败", error);
  232. // 在这里可以处理错误逻辑,比如显示错误提示等
  233. }
  234. };
  235. // 挂载
  236. onMounted(async function () {
  237. get();
  238. });
  239. //分页
  240. function handlePageChange(currentPage, pageSize) {
  241. get();
  242. }
  243. //货币条目
  244. const options = [
  245. {
  246. value: "USD",
  247. label: "USD",
  248. },
  249. {
  250. value: "EUR",
  251. label: "EUR",
  252. },
  253. {
  254. value: "JPY",
  255. label: "JPY",
  256. },
  257. {
  258. value: "GBP",
  259. label: "GBP",
  260. },
  261. {
  262. value: "AUD",
  263. label: "AUD",
  264. },
  265. ];
  266. function formatDate(value) {
  267. if (!value) return "";
  268. const date = new Date(value);
  269. const year = date.getFullYear();
  270. const month = (date.getMonth() + 1).toString().padStart(2, "0");
  271. const day = date.getDate().toString().padStart(2, "0");
  272. const hours = date.getHours().toString().padStart(2, "0");
  273. const minutes = date.getMinutes().toString().padStart(2, "0");
  274. const seconds = date.getSeconds().toString().padStart(2, "0");
  275. return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  276. }
  277. function formatDateTwe(value) {
  278. if (!value) return "";
  279. const date = new Date(value);
  280. const year = date.getFullYear();
  281. const month = (date.getMonth() + 1).toString().padStart(2, "0");
  282. const day = date.getDate().toString().padStart(2, "0");
  283. return `${year}-${month}-${day}`;
  284. }
  285. // //表格高度
  286. // const tableHeight = computed(function () {
  287. // return (getObj.value.pageSize + 1) * 50 + "px";
  288. // });
  289. // 新增数据规则
  290. // 表单验证ref
  291. const Ref = ref(null);
  292. const handleStartTimeChange = () => {
  293. Ref.value.validateField("endTime");
  294. };
  295. const checkStartTime = function (rule, value, callback) {
  296. if (value <= new Date()) {
  297. callback(new Error("开始时间不能小于当前时间"));
  298. } else {
  299. callback();
  300. }
  301. };
  302. const checkEndTime = function (rule, value, callback) {
  303. if (value <= new Date()) {
  304. callback(new Error("结束时间不能小于当前时间"));
  305. } else if (value <= rateAdd.value.startTime) {
  306. callback(new Error("结束时间不能小于开始时间"));
  307. } else {
  308. callback();
  309. }
  310. };
  311. const checkFreeGoldRadio = function (rule, value, callback) {
  312. if (value == "0" || value == null || value == "") {
  313. callback(new Error("请输入汇率比"));
  314. } else if (value < 0 || isNaN(value)) {
  315. callback(new Error("请输入正确的格式"));
  316. } else {
  317. callback();
  318. }
  319. };
  320. const rules = reactive({
  321. currency: [{ required: true, message: "请选择货币名称", trigger: "blur" }],
  322. exchangeRate: [{ validator: checkFreeGoldRadio, trigger: "blur" }],
  323. startTime: [
  324. { required: true, message: "请选择开始时间", trigger: "blur" },
  325. { validator: checkStartTime, trigger: "blur" },
  326. ],
  327. endTime: [
  328. { required: true, message: "请选择结束时间", trigger: "blur" },
  329. { validator: checkEndTime, trigger: "blur" },
  330. ],
  331. });
  332. // 重置的按钮
  333. const handledelete = function () {
  334. value1.value = {};
  335. startTime.value = "";
  336. endTime.value = "";
  337. };
  338. // 验证跳转输入框的数字是否合法
  339. const checkNumber = function () {
  340. if (typeof parseInt(getObj.value.pageNum) === "number") {
  341. console.log(
  342. "总共有多少页" + Math.ceil(total.value / getObj.value.pageSize)
  343. );
  344. if (
  345. getObj.value.pageNum > 0 &&
  346. getObj.value.pageNum <= Math.ceil(total.value / getObj.value.pageSize)
  347. ) {
  348. getObj.value.pageNum = parseInt(getObj.value.pageNum);
  349. console.log("输入的数字合法");
  350. get();
  351. } else {
  352. //提示
  353. ElMessage({
  354. type: "error",
  355. message: "请检查输入内容",
  356. });
  357. }
  358. } else {
  359. //提示
  360. ElMessage({
  361. type: "error",
  362. message: "请检查输入内容",
  363. });
  364. }
  365. };
  366. // 删除=========================================================
  367. // 删除按钮
  368. // 删除按钮的气泡弹出框确认按钮
  369. const delConfirm = async function (row) {
  370. try {
  371. // 发送POST请求
  372. const result = await API.post(
  373. "http://39.99.159.73:20090/rates/delete/ " + row.rateId,
  374. {}
  375. );
  376. // 将响应结果存储到响应式数据中
  377. console.log("请求成功", result);
  378. get();
  379. } catch (error) {
  380. console.log("请求失败", error);
  381. // 在这里可以处理错误逻辑,比如显示错误提示等
  382. }
  383. };
  384. //这是限制输入小数不超过七位的限制方法
  385. function handleInput(value) {
  386. // 限制小数点后7位,这里使用正则表达式来实现
  387. rateAdd.value.exchangeRate = value
  388. .replace(/(\.\d{7})\d+/, "$1")
  389. .replace(/^(\d+)(\.\d{0,7})?$/, "$1$2");
  390. }
  391. </script>
  392. <template>
  393. <!-- 这是主页面 -->
  394. <el-row>
  395. <el-col>
  396. <el-card>
  397. <!-- 这是时间 -->
  398. <div class="demo-range">
  399. 时间
  400. <el-date-picker
  401. v-model="value1"
  402. type="daterange"
  403. range-separator="至"
  404. start-placeholder="开始时间"
  405. end-placeholder="结束时间"
  406. :size="size"
  407. value-format="YYYY-MM-DD"
  408. />
  409. <!-- 按钮 -->
  410. <el-button
  411. class="button-item"
  412. type="primary"
  413. style="float: right"
  414. @click="search()"
  415. >查询</el-button
  416. >
  417. <el-button
  418. class="button-item"
  419. style="float: right"
  420. @click="handledelete"
  421. >重置</el-button
  422. >
  423. </div>
  424. </el-card>
  425. </el-col>
  426. </el-row>
  427. <el-row>
  428. <el-col>
  429. <el-card class="box-card" style="max-width: 100%">
  430. <!-- 添加 -->
  431. <div class="add-item">
  432. <el-button
  433. style="color: #048efb; border: 1px solid #048efb"
  434. @click="regeAdd = true"
  435. >新增汇率</el-button
  436. >
  437. </div>
  438. <!-- 表格 -->
  439. <div>
  440. <el-table
  441. :data="tableData"
  442. v-if="(tableData.flag = 1)"
  443. :height="tableHeight"
  444. style="width: 100%"
  445. >
  446. <el-table-column
  447. type="index"
  448. label="序号"
  449. width="100px"
  450. fixed="left"
  451. >
  452. <template #default="scope">
  453. <span>{{
  454. scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
  455. }}</span>
  456. </template>
  457. </el-table-column>
  458. <el-table-column prop="currency" label="货币名称" :span="2" />
  459. <el-table-column prop="exchangeRate" label="汇率" :span="2">
  460. <template #default="scope">
  461. <p>
  462. {{ scope.row.exchangeRate }}{{ scope.row.currency }} 1新币
  463. </p>
  464. </template>
  465. </el-table-column>
  466. <el-table-column prop="createTime" label="添加时间" :span="3">
  467. <template #default="scope">
  468. <span>{{ formatDate(scope.row.createTime) }}</span>
  469. </template>
  470. </el-table-column>
  471. <el-table-column prop="adminName" label="提交人" :span="1" />
  472. <el-table-column prop="status" label="状态">
  473. <template #default="scope">
  474. <span v-if="scope.row.status === 1">
  475. <div class="status">
  476. <span class="green-dot"></span>
  477. <span>使用中</span>
  478. </div>
  479. </span>
  480. <span v-if="scope.row.status === 0">
  481. <div class="status">
  482. <span class="red-dot"></span>
  483. <span>未开始</span>
  484. </div>
  485. </span>
  486. <span v-if="scope.row.status === 2">
  487. <div class="status">
  488. <span class="grey-dot"></span>
  489. <span>已过期</span>
  490. </div>
  491. </span>
  492. </template>
  493. </el-table-column>
  494. <el-table-column prop="startTime" label="持续时间" :span="10">
  495. <template #default="scope">
  496. <span>{{ formatDateTwe(scope.row.startTime) }}</span>
  497. <span>---</span>
  498. <span>{{ formatDateTwe(scope.row.endTime) }}</span>
  499. </template>
  500. </el-table-column>
  501. <el-table-column label="操作" :span="3">
  502. <template #default="scope">
  503. <el-button
  504. type="text"
  505. @click="
  506. regeEdit = true;
  507. getEditData(scope.row);
  508. "
  509. >编辑</el-button
  510. >
  511. <el-popconfirm
  512. title="确定将此条活动删除吗?"
  513. @confirm="delConfirm"
  514. >
  515. <template #reference>
  516. <el-button type="primary" text> 删除 </el-button>
  517. </template>
  518. <template #actions="{ confirm, cancel }">
  519. <el-button size="small" @click="cancel">取消</el-button>
  520. <el-button
  521. type="primary"
  522. size="small"
  523. @click="confirm(scope.row)"
  524. >
  525. 确定
  526. </el-button>
  527. </template>
  528. </el-popconfirm>
  529. </template>
  530. </el-table-column>
  531. </el-table>
  532. </div>
  533. <!-- 分页 -->
  534. <div class="pagination">
  535. <el-pagination
  536. background
  537. :page-size="getObj.pageSize"
  538. layout="slot"
  539. :total="total"
  540. >
  541. <div>{{ total }},每页</div>
  542. <el-select
  543. v-model="getObj.pageSize"
  544. class="page-size"
  545. @change="get()"
  546. style="width: 80px"
  547. >
  548. <el-option
  549. v-for="item in [5, 10, 20, 50, 100]"
  550. :key="item"
  551. :label="item"
  552. :value="item"
  553. ></el-option>
  554. </el-select>
  555. <div></div>
  556. </el-pagination>
  557. <el-pagination
  558. background
  559. layout="prev, pager, next, slot"
  560. :page-size="getObj.pageSize"
  561. :total="total"
  562. :current-page="getObj.pageNum"
  563. @current-change="get"
  564. >
  565. <div>跳至</div>
  566. <el-input
  567. v-model="getObj.pageNum"
  568. style="width: 40px"
  569. @change="checkNumber"
  570. />
  571. <div></div>
  572. </el-pagination>
  573. </div>
  574. </el-card>
  575. </el-col>
  576. </el-row>
  577. <!-- 这是添加弹窗 -->
  578. <el-dialog
  579. v-model="regeAdd"
  580. title="新增汇率"
  581. width="500"
  582. :close-on-click-modal="false"
  583. >
  584. <template #footer>
  585. <el-form
  586. ref="Ref"
  587. style="max-width: 600px"
  588. :model="rateAdd"
  589. :rules="rules"
  590. label-width="auto"
  591. class="demo-ruleForm"
  592. :size="formSize"
  593. status-icon
  594. >
  595. <el-form-item prop="currency" label="货币名称:">
  596. <el-select
  597. v-model.number="rateAdd.currency"
  598. placeholder="请选择"
  599. style="width: 240px"
  600. >
  601. <el-option
  602. v-for="item in options"
  603. :key="item.value"
  604. :label="item.label"
  605. :value="item.value"
  606. />
  607. </el-select>
  608. </el-form-item>
  609. <el-form-item prop="exchangeRate" label="汇率:">
  610. <el-input
  611. v-model="rateAdd.exchangeRate"
  612. @update:modelValue="handleInput"
  613. style="width: 120px"
  614. />
  615. <p class="unit">:1</p>
  616. <p>
  617. (提示当前规则每 {{ rateAdd.exchangeRate }}
  618. {{ rateAdd.currency }}可兑换 1 新币)
  619. </p>
  620. </el-form-item>
  621. <el-form-item prop="adminId" label="提交人:">
  622. <el-input :value="adminData.name" disabled style="width: 240px" />
  623. </el-form-item>
  624. <el-form-item prop="startTime" label="开始时间:">
  625. <el-date-picker
  626. v-model="rateAdd.startTime"
  627. type="date"
  628. placeholder="请选择时间"
  629. :default-value="new Date()"
  630. @change="handleStartTimeChange"
  631. value-format="YYYY-MM-DD"
  632. />
  633. </el-form-item>
  634. <el-form-item prop="endTime" label="结束时间:">
  635. <el-date-picker
  636. v-model="rateAdd.endTime"
  637. type="date"
  638. placeholder="请选择时间"
  639. :default-value="new Date()"
  640. value-format="YYYY-MM-DD"
  641. />
  642. </el-form-item>
  643. <el-form-item>
  644. <div class="dialog-footer">
  645. <el-button type="primary" @click="throttledAdd">添加</el-button>
  646. <el-button @click="regeAdd = false">取消</el-button>
  647. </div>
  648. </el-form-item>
  649. </el-form>
  650. </template>
  651. </el-dialog>
  652. <!-- 这是编辑弹窗 -->
  653. <el-dialog
  654. v-model="regeEdit"
  655. title="修改汇率"
  656. width="500"
  657. :close-on-click-modal="false"
  658. >
  659. <template #footer>
  660. <el-form
  661. ref="ruleFormRef"
  662. style="max-width: 600px"
  663. :model="rateEdit"
  664. :rules="rules"
  665. label-width="auto"
  666. class="demo-ruleForm"
  667. :size="formSize"
  668. status-icon
  669. >
  670. <el-form-item label="货币名称:">
  671. <el-select
  672. v-model="rateEdit.currency"
  673. placeholder="请选择"
  674. style="width: 240px"
  675. >
  676. <el-option
  677. v-for="item in options"
  678. :key="item.value"
  679. :label="item.label"
  680. :value="item.value"
  681. />
  682. </el-select>
  683. </el-form-item>
  684. <el-form-item label="汇率:">
  685. <el-input v-model="rateEdit.exchangeRate" style="width: 120px" />
  686. <p class="unit">:1</p>
  687. <p>
  688. (提示当前规则每 {{ rateEdit.exchangeRate }}
  689. {{ rateEdit.currency }}可兑换 1 新币)
  690. </p>
  691. </el-form-item>
  692. <el-form-item label="提交人:">
  693. <el-input disabled :value="adminData.name" style="width: 240px" />
  694. </el-form-item>
  695. <el-form-item label="开始时间:">
  696. <el-date-picker
  697. v-model="rateEdit.startTime"
  698. type="date"
  699. placeholder="请选择时间"
  700. :default-value="new Date()"
  701. value-format="YYYY-MM-DD"
  702. />
  703. </el-form-item>
  704. <el-form-item label="结束时间:">
  705. <el-date-picker
  706. v-model="rateEdit.endTime"
  707. type="date"
  708. placeholder="请选择时间"
  709. :default-value="new Date()"
  710. value-format="YYYY-MM-DD"
  711. />
  712. </el-form-item>
  713. <el-form-item>
  714. <div class="dialog-footer">
  715. <el-button type="primary" @click="edit">修改</el-button>
  716. <el-button @click="regeEdit = false">取消</el-button>
  717. </div>
  718. </el-form-item>
  719. </el-form>
  720. </template>
  721. </el-dialog>
  722. </template>
  723. <style scoped>
  724. p {
  725. margin: 0px;
  726. }
  727. .el-form-item {
  728. margin-left: 70px;
  729. }
  730. .ad {
  731. margin-left: 10px;
  732. }
  733. .pagination {
  734. margin-top: 20px;
  735. }
  736. .box-card {
  737. margin-top: 20px;
  738. }
  739. .button-item {
  740. margin-left: 10px;
  741. }
  742. .add-item {
  743. margin-bottom: 10px;
  744. }
  745. el-table-column {
  746. text-align: center;
  747. }
  748. p {
  749. color: rgb(150, 150, 150);
  750. }
  751. .unit {
  752. margin-left: 10px;
  753. }
  754. .el-card {
  755. padding: 0px;
  756. }
  757. .pagination {
  758. display: flex;
  759. }
  760. .status {
  761. display: flex;
  762. }
  763. </style>