operation.vue 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. <template>
  2. <view class="container">
  3. <view v-if="!menushow" class="main">
  4. <view class="u-page">
  5. <!-- 一、查询条件 -->
  6. <view class="query-card">
  7. <view class="query-row">
  8. <uni-datetime-picker
  9. class="query-item"
  10. type="datetime"
  11. :hideSecond="true"
  12. @confirm="selectStartTime"
  13. v-model="StartTime"
  14. >
  15. <view class="query-picker-inner">
  16. <u-icon name="calendar" size="16" color="#2277fb"></u-icon>
  17. <text class="query-picker-text">{{
  18. StartTime ? StartTime.slice(0, 10) : "开始日期"
  19. }}</text>
  20. </view>
  21. </uni-datetime-picker>
  22. <uni-datetime-picker
  23. class="query-item"
  24. type="datetime"
  25. :hideSecond="true"
  26. @confirm="selectEndTime"
  27. v-model="EndTime"
  28. >
  29. <view class="query-picker-inner">
  30. <u-icon name="calendar" size="16" color="#2277fb"></u-icon>
  31. <text class="query-picker-text">{{
  32. EndTime ? EndTime.slice(0, 10) : "结束日期"
  33. }}</text>
  34. </view>
  35. </uni-datetime-picker>
  36. <view class="query-btn query-btn-query" @click="checkHistoryData">
  37. 查询
  38. </view>
  39. </view>
  40. </view>
  41. <!-- 二、数据列表 -->
  42. <u-list class="historycontainer">
  43. <template v-if="historyData.length > 0">
  44. <u-list-item
  45. class="itemback"
  46. v-for="(item, index) in historyData"
  47. :key="index"
  48. >
  49. <view class="record-time-row">
  50. <text class="record-time">{{ item.createTime }}</text>
  51. </view>
  52. <view class="record-grid">
  53. <view class="record-cell">
  54. <view class="record-icon-box">
  55. <image
  56. class="record-icon"
  57. src="/static/home/user.svg"
  58. mode="aspectFit"
  59. ></image>
  60. </view>
  61. <view class="record-cell-content">
  62. <text class="record-value">{{ item.realname || "-" }}</text>
  63. <text class="record-label">用户</text>
  64. </view>
  65. </view>
  66. <view class="record-cell">
  67. <view class="record-icon-box">
  68. <image
  69. class="record-icon"
  70. src="/static/home/ctrldevice.svg"
  71. mode="aspectFit"
  72. ></image>
  73. </view>
  74. <view class="record-cell-content">
  75. <text class="record-value">{{
  76. item.devicename || "-"
  77. }}</text>
  78. <text class="record-label">操作设备</text>
  79. </view>
  80. </view>
  81. <view class="record-cell">
  82. <view class="record-icon-box">
  83. <image
  84. class="record-icon"
  85. src="/static/home/ctrlLog.svg"
  86. mode="aspectFit"
  87. ></image>
  88. </view>
  89. <view class="record-cell-content">
  90. <text class="record-value">{{
  91. item.strremark || "-"
  92. }}</text>
  93. <text class="record-label">操作记录</text>
  94. </view>
  95. </view>
  96. </view>
  97. </u-list-item>
  98. </template>
  99. <template v-else>
  100. <!-- 空数据状态 -->
  101. <view class="empty-box">
  102. <image
  103. class="empty-img"
  104. src="/static/empty.png"
  105. mode="widthFix"
  106. ></image>
  107. <text class="empty-text">数据为空</text>
  108. </view>
  109. </template>
  110. </u-list>
  111. </view>
  112. </view>
  113. </view>
  114. </template>
  115. <script>
  116. import api from "@/api/api";
  117. import dayjs from "dayjs";
  118. import uniDatetimePicker from "../../uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue";
  119. export default {
  120. data() {
  121. return {
  122. menushow: false,
  123. TabCur: "gate",
  124. // deviceType: "gate", //设备类型
  125. StartTime: "",
  126. EndTime: "",
  127. historyData: [],
  128. };
  129. },
  130. components: {
  131. uniDatetimePicker,
  132. },
  133. props: ["showColum", "deviceType"],
  134. watch: {
  135. showColum(data) {
  136. this.colums = data;
  137. },
  138. deviceType: {
  139. handler(data) {
  140. if (data) {
  141. this.TabCur = data;
  142. // 选择设备分类,重新获取数据
  143. this.checkHistoryData();
  144. this.$emit("setMenushow", {
  145. menushow: false,
  146. });
  147. }
  148. },
  149. immediate: true,
  150. },
  151. },
  152. created() {
  153. this.colums = this.showColum;
  154. const startTime = new Date().getTime() - 3600 * 1000 * 24 * 30;
  155. const endTime = new Date();
  156. this.StartTime = dayjs(startTime).format("YYYY-MM-DD HH:mm:ss");
  157. this.EndTime = dayjs(endTime).format("YYYY-MM-DD HH:mm:ss");
  158. this.checkHistoryData();
  159. },
  160. mounted() {
  161. this.TabCur = this.deviceType;
  162. },
  163. methods: {
  164. //选择起始时间
  165. selectStartTime(e) {
  166. const startTime = e.value;
  167. const formattedTime = dayjs(startTime).format("YYYY-MM-DD HH:mm:ss");
  168. this.StartTime = formattedTime;
  169. },
  170. //选择起始时间
  171. selectEndTime(e) {
  172. const endTime = e.value;
  173. const formattedTime = dayjs(endTime).format("YYYY-MM-DD HH:mm:ss");
  174. this.EndTime = formattedTime;
  175. },
  176. devicemenuShow(e) {
  177. this.menushow = !this.menushow;
  178. },
  179. menuClick(id) {
  180. this.TabCur = id;
  181. this.menushow = false;
  182. },
  183. //查询历史数据
  184. checkHistoryData() {
  185. const params = {
  186. createTime_begin: this.StartTime,
  187. createTime_end: this.EndTime,
  188. pageNo: 1,
  189. pageSize: 10000,
  190. devicetype: this.TabCur + "*",
  191. };
  192. new Promise((resolve, reject) => {
  193. api
  194. .getOpreateHistory(params)
  195. .then((response) => {
  196. if (response.data.code == 200) {
  197. this.historyData = response.data.result.records;
  198. } else {
  199. resolve(response);
  200. }
  201. })
  202. .catch((error) => {
  203. reject(error);
  204. });
  205. });
  206. },
  207. },
  208. destroyed() {},
  209. };
  210. </script>
  211. <style lang="scss" scoped>
  212. .container {
  213. padding: 0 !important;
  214. }
  215. .u-page {
  216. padding: 20rpx 0;
  217. box-sizing: border-box;
  218. }
  219. /* ===== 一、查询条件 ===== */
  220. .query-card {
  221. padding: 24rpx;
  222. background-color: #ffffff;
  223. border-radius: 16rpx;
  224. box-shadow: 0 4rpx 16rpx rgba(41, 121, 255, 0.06);
  225. margin-bottom: 20rpx;
  226. }
  227. .query-row {
  228. display: flex;
  229. align-items: center;
  230. }
  231. .query-row > * {
  232. flex: 1;
  233. min-width: 0;
  234. margin-right: 16rpx;
  235. }
  236. .query-row > *:last-child {
  237. margin-right: 0;
  238. }
  239. .query-item {
  240. flex: 1;
  241. min-width: 0;
  242. }
  243. .query-picker-inner {
  244. height: 64rpx;
  245. padding: 0 12rpx;
  246. border: 1rpx solid #2277fb;
  247. border-radius: 8rpx;
  248. background: #ffffff;
  249. display: flex;
  250. align-items: center;
  251. justify-content: center;
  252. box-sizing: border-box;
  253. }
  254. .query-picker-text {
  255. margin-left: 8rpx;
  256. font-size: 24rpx;
  257. font-weight: 500;
  258. color: #2277fb;
  259. overflow: hidden;
  260. white-space: nowrap;
  261. text-overflow: ellipsis;
  262. }
  263. /* 查询按钮 */
  264. .query-btn {
  265. flex: 0 0 auto;
  266. width: 128rpx;
  267. height: 64rpx;
  268. line-height: 64rpx;
  269. text-align: center;
  270. color: #ffffff;
  271. font-size: 26rpx;
  272. border-radius: 8rpx;
  273. background: #2277fb;
  274. overflow: hidden;
  275. white-space: nowrap;
  276. text-overflow: ellipsis;
  277. }
  278. .query-btn-query {
  279. font-weight: 600;
  280. }
  281. /* ===== 二、数据区 ===== */
  282. .historycontainer {
  283. background-color: #ffffff;
  284. border-radius: 16rpx;
  285. box-shadow: 0 4rpx 16rpx rgba(41, 121, 255, 0.06);
  286. overflow: hidden;
  287. }
  288. /* 空数据状态 */
  289. .empty-box {
  290. display: flex;
  291. flex-direction: column;
  292. align-items: center;
  293. padding: 60rpx 40rpx 40rpx;
  294. }
  295. .empty-img {
  296. width: 60%;
  297. }
  298. .empty-text {
  299. margin-top: 30rpx;
  300. font-size: 32rpx;
  301. font-weight: bold;
  302. color: #000000;
  303. }
  304. .main {
  305. display: flex;
  306. flex-direction: column;
  307. }
  308. .itemback {
  309. padding: 20rpx;
  310. background-color: #ffffff;
  311. margin-bottom: 5rpx;
  312. }
  313. .record-time-row {
  314. margin-bottom: 12rpx;
  315. background: url("/static/operation/timeBg.png");
  316. background-size: 100% 100%;
  317. background-position: right;
  318. background-repeat: no-repeat;
  319. }
  320. .record-time {
  321. display: inline-block;
  322. padding: 12rpx 30rpx;
  323. font-size: 26rpx;
  324. font-weight: 600;
  325. color: #2663ca;
  326. }
  327. .record-grid {
  328. display: flex;
  329. flex-direction: row;
  330. align-items: stretch;
  331. }
  332. .record-cell {
  333. flex: 1;
  334. min-width: 0;
  335. display: flex;
  336. flex-direction: row;
  337. align-items: center;
  338. background: linear-gradient(
  339. to bottom,
  340. rgba(175, 195, 252, 0.6) 0%,
  341. rgba(175, 195, 252, 0.1) 100%
  342. );
  343. border-radius: 12rpx;
  344. padding: 16rpx 8rpx;
  345. box-sizing: border-box;
  346. }
  347. .record-cell + .record-cell {
  348. margin-top: 0;
  349. margin-left: 12rpx;
  350. }
  351. .record-icon-box {
  352. width: 48rpx;
  353. height: 48rpx;
  354. border-radius: 10rpx;
  355. background: #71a5f9;
  356. display: flex;
  357. align-items: center;
  358. justify-content: center;
  359. flex-shrink: 0;
  360. margin-right: 8rpx;
  361. margin-bottom: 0;
  362. }
  363. .record-icon {
  364. width: 32rpx;
  365. height: 32rpx;
  366. }
  367. .record-cell-content {
  368. flex: 1;
  369. min-width: 0;
  370. display: flex;
  371. flex-direction: column;
  372. align-items: flex-start;
  373. }
  374. .record-value {
  375. display: block;
  376. max-width: 100%;
  377. font-size: 24rpx;
  378. font-weight: 700;
  379. color: #2663ca;
  380. line-height: 1.3;
  381. overflow: hidden;
  382. text-overflow: ellipsis;
  383. white-space: nowrap;
  384. }
  385. .record-label {
  386. display: block;
  387. margin-top: 6rpx;
  388. font-size: 24rpx;
  389. color: #677799;
  390. line-height: 1.3;
  391. }
  392. </style>