index.vue 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. <template>
  2. <div class="p-4">
  3. <div class="userLogin-header">
  4. <div class="userLogin-title">登录日志</div>
  5. <div class="handle-btns">
  6. <span class="label-item">操作类型:</span>
  7. <div class="select-item">
  8. <a-select v-model:value="opt" :options="selectOpt">
  9. </a-select>
  10. </div>
  11. <span class="label-item">查询时间:</span>
  12. <div class="input-item">
  13. <a-range-picker :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss"
  14. :placeholder="['开始时间', '结束时间']" v-model:value="searchDate" />
  15. </div>
  16. <a-button class="btn" @click="resetForm">重置</a-button>
  17. <a-button class="btn" type="primary" @click="searchTable">查询</a-button>
  18. </div>
  19. </div>
  20. <div class="userLogin-body">
  21. <div class="body-header">
  22. <div class="item-title">登录登出日志列表</div>
  23. <div class="table-btns">
  24. <a-button class="btn" type="primary" @click="getLoginData" title="刷新">
  25. <RedoOutlined />
  26. </a-button>
  27. </div>
  28. </div>
  29. <div class="body-content">
  30. <a-table :columns="columns" :data-source="tableData" :bordered="true">
  31. <template #STATE="{ record }">
  32. <span>{{ record.SFCG ? '成功' : '失败' }}</span>
  33. </template>
  34. <template #operation="{ record }">
  35. <a-tooltip title="详情" color="#2db7f5">
  36. <a @click="openDialog(record)">
  37. <FormOutlined /> 详情
  38. </a>
  39. </a-tooltip>
  40. </template>
  41. </a-table>
  42. </div>
  43. </div>
  44. <LoginDrawer v-if="ifShowDialog" @closeDialog="ifShowDialog = false" :formData="formData"
  45. :drawerTitle="drawerTitle">
  46. </LoginDrawer>
  47. </div>
  48. </template>
  49. <script>
  50. import { defineComponent, reactive, ref, toRefs, computed, onMounted, watch } from 'vue';
  51. import LoginDrawer from './LoginDrawer.vue';
  52. import { getLoginList } from '/@/api/sys/log';
  53. import { FormOutlined, RedoOutlined } from '@ant-design/icons-vue';
  54. import moment from 'moment';
  55. export default defineComponent({
  56. name: 'userLogin',
  57. components: { LoginDrawer, FormOutlined, RedoOutlined },
  58. setup() {
  59. onMounted(() => {
  60. getLoginData();
  61. });
  62. const data = reactive({
  63. tableData: [],//表格数据
  64. formData: {
  65. ID: "",
  66. USERNAME: "",
  67. USERID: "",
  68. OPT: "",
  69. CZSM: "",
  70. SFCG: 0,
  71. CJRQ: "",
  72. },
  73. drawerTitle: "日志记录详情",
  74. ifShowDialog: false
  75. });
  76. const selectOpt = ref([])
  77. const searchForm = reactive({
  78. opt: "",//查询类型
  79. searchDate: [moment().subtract(30, 'days'), moment()],//查询时间
  80. })
  81. //获取所有日志
  82. const getLoginData = () => {
  83. data.tableData = []
  84. selectOpt.value = []
  85. let param = {
  86. page: 1,
  87. rows: 10000000,
  88. startCreateTimeStr: searchForm.searchDate[0].format('YYYY-MM-DD HH:mm:ss'),
  89. endCreateTimeStr: searchForm.searchDate[1].format('YYYY-MM-DD HH:mm:ss'),
  90. keyStr: searchForm.opt
  91. }
  92. getLoginList(param).then(res => {
  93. if (res.resp_msg === "获取成功!") {
  94. let resData = res.datas.records
  95. let optArr = []
  96. resData.forEach((item, index) => {
  97. optArr.push(item.OPT)
  98. data.tableData.push({
  99. key: item.ID,
  100. ...item
  101. })
  102. })
  103. let set1 = new Set(optArr)
  104. let newArr = [...set1]
  105. newArr.forEach(item => {
  106. selectOpt.value.push({
  107. value: item,
  108. label: item
  109. })
  110. })
  111. searchForm.opt = selectOpt.value[0].value
  112. }
  113. })
  114. }
  115. //表格列
  116. const columns = [
  117. {
  118. title: '用户名称',
  119. align: 'center',
  120. dataIndex: 'USERNAME',
  121. key: 'USERNAME',
  122. width: "200px"
  123. },
  124. {
  125. title: '用户ID',
  126. align: 'center',
  127. dataIndex: 'USERID',
  128. key: 'USERID',
  129. width: "400px"
  130. },
  131. {
  132. title: '操作类型',
  133. align: 'center',
  134. dataIndex: 'OPT',
  135. key: 'OPT',
  136. width: "150px"
  137. },
  138. {
  139. title: '操作说明',
  140. align: 'center',
  141. dataIndex: 'CZSM',
  142. key: 'CZSM',
  143. width: "320px"
  144. },
  145. {
  146. title: '操作状态',
  147. align: 'center',
  148. dataIndex: 'SFCG',
  149. slots: {
  150. customRender: 'STATE',
  151. },
  152. width: "100px"
  153. },
  154. {
  155. title: '操作时间',
  156. align: 'center',
  157. dataIndex: 'CJRQ',
  158. key: 'CJRQ',
  159. width: "230px"
  160. },
  161. {
  162. title: '操作',
  163. align: 'center',
  164. dataIndex: 'operation',
  165. slots: {
  166. customRender: 'operation',
  167. }
  168. },
  169. ]
  170. //重置表格
  171. const resetForm = () => {
  172. searchForm.opt = selectOpt.value[0].value
  173. searchForm.searchDate = [moment().subtract(30, 'days'), moment()]
  174. }
  175. //表格查询功能
  176. const searchTable = () => {
  177. getLoginData();
  178. }
  179. //打开详情弹窗
  180. const openDialog = (record) => {
  181. data.formData = { ...record }
  182. data.drawerTitle = '日志记录详情'
  183. data.ifShowDialog = true
  184. }
  185. return {
  186. columns,
  187. selectOpt,
  188. ...toRefs(data),
  189. ...toRefs(searchForm),
  190. // func
  191. getLoginData,
  192. resetForm,
  193. searchTable,
  194. openDialog
  195. };
  196. },
  197. });
  198. </script>
  199. <style lang="less" scoped>
  200. .p-4 {
  201. height: 100%;
  202. .userLogin-header {
  203. padding: 10px;
  204. width: 100%;
  205. height: 70px;
  206. background-color: #fff;
  207. display: flex;
  208. justify-content: space-between;
  209. align-items: center;
  210. .userLogin-title {
  211. font-size: 16px;
  212. font-weight: 500;
  213. margin-left: 20px;
  214. user-select: none;
  215. }
  216. .handle-btns {
  217. margin-right: 20px;
  218. display: flex;
  219. align-items: center;
  220. .label-item {
  221. width: 80px;
  222. }
  223. .select-item {
  224. width: 130px;
  225. }
  226. .input-item {
  227. width: 350px;
  228. }
  229. .btn {
  230. margin-left: 10px;
  231. }
  232. }
  233. }
  234. .userLogin-body {
  235. padding: 0 30px;
  236. margin-top: 20px;
  237. width: 100%;
  238. // height: 800px;
  239. height: calc(100% - 90px);
  240. background-color: #fff;
  241. .body-header {
  242. display: flex;
  243. height: 80px;
  244. width: 100%;
  245. justify-content: space-between;
  246. align-items: center;
  247. .item-title {
  248. height: 40px;
  249. line-height: 40px;
  250. font-size: 16px;
  251. user-select: none;
  252. }
  253. .table-btns {
  254. .btn {
  255. margin-right: 10px;
  256. &:last-child {
  257. margin-right: 0;
  258. }
  259. }
  260. }
  261. }
  262. .body-content {
  263. padding-bottom: 20px;
  264. height: calc(100% - 80px);
  265. a {
  266. margin-right: 10px;
  267. }
  268. }
  269. }
  270. }
  271. </style>