deepchart后台管理系统
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.

426 lines
9.9 KiB

4 weeks ago
3 weeks ago
3 weeks ago
4 weeks ago
  1. <template>
  2. <div class="page-container">
  3. <!-- 搜索区域 -->
  4. <div class="search-container">
  5. <div class="search-group">
  6. <span class="form-label">账号</span>
  7. <el-input
  8. v-model="searchForm.dccode"
  9. placeholder="请输入账号"
  10. clearable
  11. style="height: 36px; width: 140px"
  12. />
  13. <span class="form-label">地区</span>
  14. <el-select
  15. v-model="searchForm.country"
  16. placeholder="请选择地区"
  17. clearable
  18. filterable
  19. style="height: 36px; width: 160px"
  20. :loading="isRegionLoading"
  21. >
  22. <el-option
  23. v-for="region in regionList"
  24. :key="region.ID"
  25. :label="region.Name"
  26. :value="region.ID"
  27. />
  28. </el-select>
  29. <span class="form-label">物品类型</span>
  30. <el-select
  31. v-model="searchForm.prize_type"
  32. placeholder="请选择类型"
  33. style="height: 36px; width: 160px"
  34. clearable
  35. >
  36. <el-option
  37. v-for="item in typeOptions"
  38. :key="item.value"
  39. :label="item.label"
  40. :value="item.value"
  41. />
  42. </el-select>
  43. </div>
  44. <div class="button-group">
  45. <el-button type="primary" @click="search">搜索</el-button>
  46. <el-button type="success" @click="exportExcel">导出Excel列表</el-button>
  47. <el-button color="#626aef" @click="exportList">查看导出列表</el-button>
  48. <el-button type="primary" @click="resetBn">重置</el-button>
  49. </div>
  50. </div>
  51. <!-- 数据 -->
  52. <el-table
  53. :data="tableData"
  54. style="width: 100%; margin-top: 20px"
  55. header-cell-class-name="table-header"
  56. @sort-change="handleSortChange"
  57. :default-sort="{ prop: null, order: null }"
  58. class="table-rounded"
  59. :loading="tableLoading"
  60. >
  61. <el-table-column
  62. prop="id"
  63. label="序号"
  64. align="center"
  65. header-align="center"
  66. width="80"
  67. >
  68. <template #default="scope">
  69. {{ (currentPage - 1) * pageSize + scope.$index + 1 }}
  70. </template>
  71. </el-table-column>
  72. <el-table-column
  73. prop="dccode"
  74. label="账号"
  75. align="center"
  76. header-align="center"
  77. />
  78. <el-table-column
  79. prop="name"
  80. label="姓名"
  81. align="center"
  82. header-align="center"
  83. />
  84. <el-table-column
  85. prop="market"
  86. label="地区"
  87. align="center"
  88. header-align="center"
  89. />
  90. <el-table-column
  91. prop="prize_name"
  92. label="物品名称"
  93. align="center"
  94. header-align="center"
  95. />
  96. <el-table-column
  97. prop="stick_type"
  98. label="福签"
  99. align="center"
  100. header-align="center"
  101. />
  102. <el-table-column
  103. prop="num"
  104. label="数量"
  105. align="center"
  106. header-align="center"
  107. />
  108. <el-table-column
  109. prop="created_at"
  110. label="时间"
  111. align="center"
  112. header-align="center"
  113. />
  114. </el-table>
  115. <!-- 分页组件 -->
  116. <div class="demo-pagination-block">
  117. <el-pagination
  118. @size-change="handleSizeChange"
  119. @current-change="handleCurrentChange"
  120. :current-page="currentPage"
  121. :page-sizes="[10, 15, 20, 50, 100]"
  122. :page-size="pageSize"
  123. layout="total, sizes, prev, pager, next, jumper"
  124. :total="datatotal"
  125. />
  126. </div>
  127. </div>
  128. </template>
  129. <script setup>
  130. import { ref, reactive, onMounted } from "vue";
  131. import { ElMessage } from "element-plus";
  132. import { marketListApi } from "../../api/userPermissions";
  133. import { userLuckyDrawListApi, exportUserLuckyDrawListApi } from "../../api/eventManagement";
  134. import router from "../../router";
  135. // token
  136. const token = localStorage.getItem("token");
  137. const typeOptions = ref([
  138. { label: "金币", value: 2 },
  139. { label: "金豆", value: 3 },
  140. { label: "Token", value: 1 },
  141. { label: "实物", value: 4 },
  142. { label: "模板", value: 5 },
  143. ]);
  144. // 搜索表单
  145. const searchForm = reactive({
  146. dccode: "",
  147. country: "",
  148. prize_type: "",
  149. });
  150. // 排序参数
  151. const sortProp = ref(null);
  152. const sortOrder = ref(null);
  153. // 表格数据
  154. const tableData = ref([]);
  155. const tableLoading = ref(false);
  156. const datatotal = ref(0);
  157. // 分页参数
  158. const currentPage = ref(1);
  159. const pageSize = ref(15);
  160. // 地区下拉框
  161. const regionList = ref([]);
  162. const isRegionLoading = ref(false);
  163. // 来源下拉框
  164. const originList = ref([]);
  165. const isOriginLoading = ref(false);
  166. // 禁用当前日期之前的日期(当天0点之前的时间)
  167. const disabledDate = (time) => {
  168. return time.getTime() < new Date().getTime() - 8.64e7;
  169. };
  170. // 格式化日期
  171. const formatDate = (date) => {
  172. if (!date) return "";
  173. const year = date.getFullYear();
  174. const month = String(date.getMonth() + 1).padStart(2, "0");
  175. const day = String(date.getDate()).padStart(2, "0");
  176. return `${year}/${month}/${day}`;
  177. };
  178. // 校验HLid
  179. const checkHlids = () => {
  180. // 非空
  181. if (!hlidsInput.value.trim()) {
  182. ElMessage.error("请输入HLid");
  183. return false;
  184. }
  185. // 处理输入:去空、去重,转数组
  186. const hlidList = hlidsInput.value
  187. .split("\n")
  188. .map((item) => item.trim())
  189. .filter((item) => item)
  190. .filter((item, index, self) => self.indexOf(item) === index); // 去重
  191. // 数量校验(最多1000个)
  192. if (hlidList.length > 1000) {
  193. ElMessage.error("HLid数量不能超过1000个");
  194. return false;
  195. }
  196. // 格式校验(8位数字)
  197. const hlidReg = /^\d{8}$/;
  198. for (const hlid of hlidList) {
  199. if (!hlidReg.test(hlid)) {
  200. ElMessage.error(`有HLid格式错误:${hlid},请重新输入`);
  201. return false;
  202. }
  203. }
  204. return true;
  205. };
  206. // 重置表单数据
  207. const resetForm = () => {
  208. hlidsInput.value = "";
  209. timeType.value = "";
  210. expireTime.value = "";
  211. delayValue.value = "";
  212. delayUnit.value = "";
  213. remark.value = "";
  214. operator.value = "";
  215. };
  216. // 获取地区列表
  217. const fetchRegionList = async () => {
  218. try {
  219. isRegionLoading.value = true;
  220. const data = await marketListApi({
  221. token: token,
  222. app_form: "en",
  223. });
  224. regionList.value = data.list;
  225. } catch (error) {
  226. console.error("获取地区列表失败:", error);
  227. regionList.value = [];
  228. } finally {
  229. isRegionLoading.value = false;
  230. }
  231. };
  232. // 获取表格数据
  233. const fetchTableData = async () => {
  234. try {
  235. tableLoading.value = true;
  236. const requestParams = {
  237. token: token,
  238. dccode: searchForm.dccode,
  239. country: searchForm.country,
  240. prize_type: searchForm.prize_type,
  241. page: currentPage.value,
  242. page_size: pageSize.value,
  243. };
  244. const data = await userLuckyDrawListApi(requestParams);
  245. tableData.value = data.list;
  246. datatotal.value = data.total;
  247. } catch (error) {
  248. console.error("获取表格数据失败:", error);
  249. tableData.value = [];
  250. datatotal.value = 0;
  251. } finally {
  252. tableLoading.value = false;
  253. }
  254. };
  255. // 组件挂载时:获取地区列表 + 初始化表格数据
  256. onMounted(() => {
  257. fetchRegionList();
  258. fetchTableData();
  259. });
  260. // 搜索按钮
  261. const search = () => {
  262. currentPage.value = 1;
  263. fetchTableData();
  264. };
  265. // 导出Excel列表按钮
  266. const exportExcel = async () => {
  267. const requestParams = {
  268. token: token,
  269. dccode: searchForm.dccode,
  270. country: searchForm.country,
  271. prize_type: searchForm.prize_type,
  272. };
  273. const data = await exportUserLuckyDrawListApi(requestParams);
  274. console.log(data);
  275. if (data != "") {
  276. ElMessage.success("已导出");
  277. }
  278. };
  279. // 查看导出列表按钮
  280. const exportList = () => {
  281. router.push({
  282. path: '/userPermissions/export'
  283. });
  284. };
  285. // 重置按钮
  286. const resetBn = () => {
  287. searchForm.dccode = "";
  288. searchForm.country = "";
  289. searchForm.prize_type = "";
  290. currentPage.value = 1;
  291. pageSize.value = 15;
  292. fetchTableData();
  293. };
  294. // 分页方法
  295. const handleSizeChange = (val) => {
  296. pageSize.value = val;
  297. fetchTableData();
  298. console.log(`每页 ${val}`);
  299. };
  300. const handleCurrentChange = (val) => {
  301. currentPage.value = val;
  302. fetchTableData();
  303. console.log(`当前页: ${val}`);
  304. };
  305. </script>
  306. <style scoped>
  307. /* 父容器 */
  308. .page-container {
  309. position: relative;
  310. min-height: 600px;
  311. }
  312. /* 搜索区域 */
  313. .search-container {
  314. display: flex;
  315. height: auto;
  316. justify-content: center;
  317. align-items: flex-start;
  318. gap: 12px;
  319. align-self: stretch;
  320. border-radius: 8px;
  321. background: #fefaf9;
  322. box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.25);
  323. padding: 15px;
  324. margin-bottom: 20px;
  325. flex-wrap: wrap;
  326. }
  327. .search-group {
  328. display: flex;
  329. align-items: center;
  330. gap: 15px;
  331. }
  332. /* 搜索标签文字 */
  333. .form-label {
  334. font-weight: 800 !important;
  335. font-size: 15px;
  336. color: #333;
  337. font-family: "SimHei", "Heiti SC", "Microsoft YaHei", sans-serif !important;
  338. font-weight: 500;
  339. }
  340. /* 按钮组 */
  341. .button-group {
  342. display: flex;
  343. align-items: center;
  344. gap: 0px !important;
  345. margin-left: auto;
  346. }
  347. /* 按钮样式 */
  348. .button-group .el-button {
  349. padding: 6px 10px !important;
  350. font-size: 14px !important;
  351. height: 36px !important;
  352. }
  353. /* 表格样式 */
  354. .table-rounded {
  355. border-radius: 12px !important;
  356. overflow: hidden !important;
  357. border: 1px solid #e4e7ed !important;
  358. height: 750px;
  359. }
  360. .table-header {
  361. text-align: center !important;
  362. font-weight: 800 !important;
  363. font-size: 15px !important;
  364. color: #333 !important;
  365. background-color: #f8f9fa !important;
  366. }
  367. .el-table__cell {
  368. border-right: none !important;
  369. border-bottom: 1px solid #e4e7ed !important;
  370. }
  371. .el-table__header th.el-table__cell {
  372. border-right: none !important;
  373. border-bottom: 1px solid #e4e7ed !important;
  374. }
  375. .el-table__row:hover .el-table__cell {
  376. background-color: #fafafa !important;
  377. }
  378. /* 分页组件样式 */
  379. .demo-pagination-block {
  380. display: flex;
  381. width: 100%;
  382. height: 44px;
  383. padding: 0 16px;
  384. align-items: center;
  385. gap: 16px;
  386. position: absolute;
  387. margin-top: 10px;
  388. border-radius: 0 0 3px 3px;
  389. border-top: 1px solid #eaeaea;
  390. background: #fefbfb;
  391. box-sizing: border-box;
  392. }
  393. </style>