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.

403 lines
10 KiB

4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
6 months ago
4 months ago
6 months ago
6 months ago
4 months ago
6 months ago
4 months ago
6 months ago
4 months ago
6 months ago
4 months ago
4 months ago
6 months ago
4 months ago
4 months ago
6 months ago
9 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
9 months ago
4 months ago
9 months ago
4 months ago
4 months ago
4 months ago
4 months ago
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 { onMounted, reactive, ref } from 'vue'
  3. import { ElMessage, ElMessageBox } from 'element-plus'
  4. import request from '@/util/http'
  5. import { useAdminStore } from "@/store/index.js";
  6. import { storeToRefs } from "pinia";
  7. import { permissionMapping, hasMenuPermission } from "@/utils/menuTreePermission.js"
  8. import { useI18n } from 'vue-i18n'
  9. const { t } = useI18n()
  10. const adminStore = useAdminStore()
  11. const { adminData, menuTree } = storeToRefs(adminStore)
  12. const regeEdit = ref(false)
  13. const editFormRef = ref(null)
  14. const tableData = ref([])
  15. //搜索对象
  16. const getObj = ref({
  17. pageNum: 1,
  18. pageSize: 10
  19. })
  20. const total = ref(0)
  21. const rateEdit = ref({
  22. id: null,
  23. rateName: '',
  24. num: null,
  25. adminId: null,
  26. updateTime: Date.now(),
  27. })
  28. //货币条目
  29. const rateNames = [
  30. {
  31. value: 'USD',
  32. label: 'USD'
  33. },
  34. {
  35. value: 'HKD',
  36. label: 'HKD'
  37. },
  38. {
  39. value: 'THB',
  40. label: 'THB'
  41. },
  42. {
  43. value: 'VND',
  44. label: 'VND'
  45. },
  46. {
  47. value: 'CAD',
  48. label: 'CAD'
  49. },
  50. {
  51. value: 'MYR',
  52. label: 'MYR'
  53. },
  54. {
  55. value: 'KRW',
  56. label: 'KRW'
  57. },
  58. {
  59. value: 'JPY',
  60. label: 'JPY'
  61. },
  62. {
  63. value: 'CNY',
  64. label: 'CNY'
  65. }
  66. ]
  67. // 汇率校验
  68. const checkFreeGoldRadio = function (rule, value, callback) {
  69. if (value == '0' || value == null || value == '') {
  70. callback(new Error(t('elmessage.pleaseInputRate')))
  71. } else if (value < 0 || isNaN(value)) {
  72. callback(new Error(t('elmessage.pleaseInputCorrectRateFormat')))
  73. } else {
  74. callback()
  75. }
  76. }
  77. // 定义表单验证规则
  78. const rules = reactive({
  79. num: [{ validator: checkFreeGoldRadio, trigger: 'blur' }],
  80. })
  81. // 表单大小
  82. const formSize = ref('default')
  83. const getAllRate = async function (val) {
  84. try {
  85. const result = await request({
  86. url: '/rate/selectAll',
  87. method: 'POST',
  88. data: {
  89. pageNum: getObj.value.pageNum,
  90. pageSize: getObj.value.pageSize,
  91. }
  92. })
  93. console.log('这是汇率列表 请求成功', result)
  94. tableData.value = result.data.list
  95. total.value = result.data.total
  96. } catch (error) {
  97. console.log('请求失败', error);
  98. ElMessage.error(t('elmessage.requestFailed'));
  99. }
  100. }
  101. const handlePageSizeChange = function (val) {
  102. getObj.value.pageSize = val
  103. getAllRate()
  104. }
  105. const handleCurrentChange = function (val) {
  106. getObj.value.pageNum = val
  107. getAllRate()
  108. }
  109. const getEditData = async function (row) {
  110. try {
  111. console.log('搜索参数', getObj.value)
  112. const result = await request({
  113. url: '/rate/selectById',
  114. data: { id: row.id }
  115. })
  116. console.log('根据id查 请求成功', result)
  117. rateEdit.value.id = row.id
  118. rateEdit.value.rateName = row.rateName
  119. rateEdit.value.num = row.num
  120. console.log('根据id获取的数据', rateEdit.value)
  121. rateEdit.value.adminId = adminData.value.id
  122. } catch (error) {
  123. console.log('请求失败', error)
  124. }
  125. }
  126. const hasrateShow = ref(false)
  127. const hasrateEdit = ref(false)
  128. // 初始化权限状态
  129. const initPermissions = () => {
  130. if (!menuTree.value || !menuTree.value.length) return;
  131. hasrateShow.value = hasMenuPermission(menuTree.value, permissionMapping.view_exchange_rate);
  132. hasrateEdit.value = hasMenuPermission(menuTree.value, permissionMapping.edit_exchange_rate);
  133. };
  134. // 编辑汇率
  135. const editRate = async function () {
  136. if (!hasrateEdit) {
  137. ElMessage.error(t('elmessage.noPermission'))
  138. return
  139. }
  140. // 提交前验证 汇率是否为数字
  141. rateEdit.value.num = parseFloat(rateEdit.value.num);
  142. try {
  143. console.log('搜索参数', rateEdit.value)
  144. const result = await request({
  145. url: '/rate/update',
  146. data: rateEdit.value
  147. })
  148. console.log('请求成功', result)
  149. await getAllRate()
  150. } catch (error) {
  151. console.log('请求失败', error)
  152. }
  153. }
  154. // 添加前验证
  155. const edit = () => {
  156. editFormRef.value.validate(async (valid) => {
  157. if (valid) {
  158. try {
  159. await ElMessageBox.confirm("确认修改?");
  160. await editRate();
  161. console.log("修改成功");
  162. regeEdit.value = false;
  163. } catch (error) {
  164. console.log("取消修改", error);
  165. regeEdit.value = false;
  166. }
  167. } else {
  168. ElMessage({
  169. type: "error",
  170. message: "请检查输入内容",
  171. })
  172. }
  173. })
  174. }
  175. const cancelEdit = () => {
  176. regeEdit.value = false
  177. }
  178. const handleEditDialogClose = () => {
  179. if (editFormRef.value) {
  180. getAllRate()
  181. }
  182. }
  183. // 日期格式化
  184. function formatDate(value) {
  185. if (!value) return ''
  186. const date = new Date(value)
  187. const year = date.getFullYear()
  188. const month = (date.getMonth() + 1).toString().padStart(2, '0')
  189. const day = date.getDate().toString().padStart(2, '0')
  190. const hours = date.getHours().toString().padStart(2, '0')
  191. const minutes = date.getMinutes().toString().padStart(2, '0')
  192. const seconds = date.getSeconds().toString().padStart(2, '0')
  193. return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
  194. }
  195. // 输入框过滤
  196. function handleInput(value) {
  197. // 检查是否使用了中文句号
  198. if (value.includes('。') || /[^\d.]/g.test(value)) {
  199. ElMessage.warning(t('elmessage.pleaseInputCorrectSymbol'));
  200. // value = value.replace('。', '.');
  201. }
  202. // 处理多个小数点的情况,保留第一个,移除后续的
  203. const parts = value.split('.');
  204. if (parts.length > 2) {
  205. value = parts[0] + '.' + parts.slice(1).join('');
  206. ElMessage.warning(t('elmessage.onlyOneDecimalPoint'));
  207. }
  208. // 禁止输入负数
  209. if (value.startsWith('-')) {
  210. ElMessage.warning(t('elmessage.noNegativeNumber'));
  211. value = value.substring(1);
  212. }
  213. // 最多两位小数,超过时才显示提示
  214. if (value.includes('.')) {
  215. const parts = value.split('.')
  216. // 限制整数部分最多六位
  217. if (parts[0].length > 6) {
  218. parts[0] = parts[0].slice(0, 6)
  219. ElMessage.info(t('elmessage.integerPartLimit'))
  220. }
  221. // 限制小数部分最多两位
  222. if (parts[1].length > 7) {
  223. parts[1] = parts[1].slice(0, 7)
  224. value = parts[0] + '.' + parts[1]
  225. ElMessage.info(t('elmessage.decimalPartLimit'))
  226. } else {
  227. value = parts[0] + '.' + parts[1]
  228. }
  229. } else {
  230. // 纯整数时限制最多六位
  231. if (value.length > 6) {
  232. value = value.slice(0, 6)
  233. ElMessage.info(t('elmessage.integerPartLimit'))
  234. }
  235. }
  236. // 小数点前没有数字时补0
  237. if (value.startsWith('.')) {
  238. value = '0' + value;
  239. // 需求没有,注释,先不显示
  240. // ElMessage.info('已自动补充前导0');
  241. }
  242. // 更新表单值
  243. rateEdit.value.num = value
  244. return value
  245. }
  246. onMounted(async function () {
  247. initPermissions()
  248. await getAllRate()
  249. })
  250. </script>
  251. <template>
  252. <el-card class="card2" style="width:81vw;height:92vh" v-if="hasrateShow">
  253. <el-table :data="tableData" v-if="(tableData.flag = 1)">
  254. <el-table-column type="index" :label="t('common_list.id')" width="100px" fixed="left">
  255. <template #default="scope">
  256. <span>{{
  257. scope.$index + 1 + (getObj.pageNum - 1) * getObj.pageSize
  258. }}</span>
  259. </template>
  260. </el-table-column>
  261. <el-table-column prop="rateName" :label="t('common_list.rateName')" :span="2" />
  262. <el-table-column prop="num" :label="t('common_list.num')" :span="2">
  263. <template #default="scope">
  264. <p>
  265. {{ scope.row.num }} 1
  266. </p>
  267. </template>
  268. </el-table-column>
  269. <el-table-column prop="updateTime" :label="t('common_list.updateTime')" :span="3">
  270. <template #default="scope">
  271. <span>{{ formatDate(scope.row.updateTime) }}</span>
  272. </template>
  273. </el-table-column>
  274. <el-table-column v-if="hasrateEdit" :label="t('common_list.operation')" :span="3">
  275. <template #default="scope">
  276. <el-link :underline="false" class="edit-btn" @click="() => {
  277. regeEdit = true
  278. getEditData(scope.row)
  279. }">{{ t('common.edit') }}
  280. </el-link>
  281. </template>
  282. </el-table-column>
  283. </el-table>
  284. <!-- 分页 -->
  285. <div class="pagination">
  286. <el-pagination background :page-size="getObj.pageSize" :page-sizes="[5, 10, 20, 50, 100]"
  287. layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handlePageSizeChange"
  288. @current-change="handleCurrentChange"></el-pagination>
  289. </div>
  290. </el-card>
  291. <!-- 这是编辑弹窗 -->
  292. <el-dialog align-center v-model="regeEdit" :title="t('rate.modifyRate')" width="30vw" :close-on-click-modal="false"
  293. @close="handleEditDialogClose">
  294. <el-form ref="editFormRef" :model="rateEdit" :rules="rules" label-width="auto" class="edit-form" :size="formSize"
  295. status-icon>
  296. <el-form-item prop="rateName" :label="t('common_list.rateName')">
  297. <el-input v-model="rateEdit.rateName" disabled style="width: 10vw" />
  298. </el-form-item>
  299. <el-form-item prop="num" :label="t('common_list.num')">
  300. <el-input v-model="rateEdit.num" @update:modelValue="handleInput" style="width: 120px" />
  301. <span class="unit">:1</span>
  302. </el-form-item>
  303. <div class="rate-tip">
  304. {{ t('rate.prompt1') }}
  305. <span>{{ rateEdit.num }}</span>
  306. <span>{{ rateEdit.rateName }}</span>{{ t('rate.prompt2') }}
  307. </div>
  308. </el-form>
  309. <div class="dialog-footer">
  310. <el-button type="primary" @click="edit">{{ t('common.modify') }}</el-button>
  311. <el-button @click="cancelEdit">{{ t('common.cancel') }}</el-button>
  312. </div>
  313. </el-dialog>
  314. </template>
  315. <style scoped>
  316. .card1 {
  317. background: #F3FAFE;
  318. }
  319. :deep(.el-table__header-wrapper),
  320. :deep(.el-table__body-wrapper),
  321. :deep(.el-table__cell),
  322. /* 表格 */
  323. :deep(.el-table__body td) {
  324. background-color: #F3FAFE !important;
  325. }
  326. /* 表头 */
  327. :deep(.el-table__header th) {
  328. background-color: #F3FAFE !important;
  329. }
  330. /* 鼠标悬停 */
  331. :deep(.el-table__row:hover > .el-table__cell) {
  332. background-color: #E5EBFE !important;
  333. }
  334. .pagination {
  335. margin-top: 20px;
  336. display: flex;
  337. }
  338. .edit-form {
  339. width: 35vw;
  340. height: 13vh;
  341. }
  342. .dialog-footer {
  343. display: flex;
  344. margin-left: 5vw;
  345. }
  346. .unit {
  347. margin-left: 0.5vw;
  348. }
  349. .rate-tip {
  350. hyphens: auto;
  351. margin-left: 1.4vw;
  352. }
  353. /**表单的卡片样式**/
  354. .card2 {
  355. background: #E7F4FD;
  356. }
  357. /**表头背景等**/
  358. :deep(.el-table__header-wrapper),
  359. :deep(.el-table__body-wrapper),
  360. :deep(.el-table__cell),
  361. /* 表格 */
  362. :deep(.el-table__body td) {
  363. background-color: #F3FAFE !important;
  364. }
  365. /* 表头 */
  366. :deep(.el-table__header th) {
  367. background-color: #F3FAFE !important;
  368. }
  369. /* 鼠标悬停 */
  370. :deep(.el-table__row:hover > .el-table__cell) {
  371. background-color: #E5EBFE !important;
  372. }
  373. </style>