autodoor.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888
  1. <template>
  2. <view style="overflow: auto; height: 100%">
  3. <!-- 建议放在外层 -->
  4. <u-navbar
  5. :title="name"
  6. @leftClick="backPage"
  7. :bgImage="backPic"
  8. :bgStatusImage="backPic0"
  9. >
  10. <view class="u-nav-slot" slot="left">
  11. <u-icon name="arrow-left" size="20"> </u-icon>
  12. </view>
  13. </u-navbar>
  14. <view class="main">
  15. <view class="u-page container">
  16. <div class="button-grid flcard" v-if="this.TabCur == 'gate'">
  17. <u-button
  18. type="primary"
  19. text="打开前门"
  20. @click="showPasswordDialog('frontGateOpen_S')"
  21. ></u-button>
  22. <u-button
  23. type="primary"
  24. text="关闭前门"
  25. @click="showPasswordDialog('frontGateClose_S')"
  26. ></u-button>
  27. <u-button
  28. type="primary"
  29. text="打开后门"
  30. @click="showPasswordDialog('rearGateOpen_S')"
  31. ></u-button>
  32. <u-button
  33. type="primary"
  34. text="关闭后门"
  35. @click="showPasswordDialog('rearGateClose_S')"
  36. ></u-button>
  37. <u-button
  38. type="primary"
  39. text="打开前后门"
  40. @click="showPasswordDialog('sameTimeOpen')"
  41. ></u-button>
  42. <u-button
  43. type="primary"
  44. text="关闭前后门"
  45. @click="showPasswordDialog('sameTimeClose')"
  46. ></u-button>
  47. </div>
  48. <div
  49. class="button-grid flcard"
  50. v-if="this.TabCur == 'window' && this.nwindownum == 1"
  51. >
  52. <u-button
  53. type="primary"
  54. text="设定面积"
  55. @click="showPasswordDialog('frontSetValue')"
  56. ></u-button>
  57. </div>
  58. <div
  59. class="button-grid flcard"
  60. v-if="this.TabCur == 'window' && this.nwindownum == 2"
  61. >
  62. <u-button
  63. type="primary"
  64. text="设定前窗面积"
  65. @click="showPasswordDialog('frontSetValue')"
  66. ></u-button>
  67. <u-button
  68. type="primary"
  69. text="设定后窗面积"
  70. @click="showPasswordDialog('rearSetValue')"
  71. ></u-button>
  72. </div>
  73. <div class="flcard" v-if="this.TabCur == 'gate'">
  74. <doorAnimate
  75. :gatestate1="frontGateStatus"
  76. :gatestate2="midGateStatus"
  77. :gatestate3="rearGateStatus"
  78. :height="height"
  79. :doorcount="ndoorcount"
  80. ></doorAnimate>
  81. </div>
  82. <div class="flcard" v-if="this.TabCur == 'windrect'">
  83. <windrectAnimate
  84. :state="state"
  85. :title="title"
  86. :videoURL="viedeoUrl"
  87. :height="height"
  88. :type="deviceType"
  89. ></windrectAnimate>
  90. </div>
  91. <div class="flcard" v-if="this.TabCur == 'fanlocal'">
  92. <fanlocalAnimate
  93. :fan1State="fan1State"
  94. :fan2State="fan2State"
  95. :title="title"
  96. :videoURL="viedeoUrl"
  97. :height="height"
  98. ></fanlocalAnimate>
  99. </div>
  100. <div class="flcard" v-if="this.TabCur == 'fanmain'">
  101. <fanmainAnimate
  102. ref="fanpage"
  103. style="width: 100%; min-width: 550px; height: calc(68vh - 220px)"
  104. :door1="door1"
  105. :topdoor1="topdoor1"
  106. :fundoor1="fundoor1"
  107. :door2="door2"
  108. :topdoor2="topdoor2"
  109. :fundoor2="fundoor2"
  110. :nowfengji="qidongfengji"
  111. ></fanmainAnimate>
  112. </div>
  113. <div
  114. class="flcard"
  115. v-if="this.TabCur == 'window' && this.nwindownum == 1"
  116. >
  117. <windowAnimate
  118. :windowAngle="windowAngle"
  119. :height="height"
  120. :windowcount="nwindownum"
  121. ></windowAnimate>
  122. </div>
  123. <div
  124. class="flcard"
  125. v-if="this.TabCur == 'window' && this.nwindownum == 2"
  126. >
  127. <windowAnimate
  128. :windowAngle="windowAngle"
  129. :windowAngle1="windowAngle1"
  130. :height="height"
  131. :windowcount="nwindownum"
  132. ></windowAnimate>
  133. </div>
  134. <div
  135. class="flcard"
  136. style="height: calc(100vh - 80px); overflow-y: auto; padding: 0px"
  137. >
  138. <u-row
  139. :gutter="0"
  140. v-for="(row, index) in rows"
  141. style="width: calc(100vw - 50px); float: left"
  142. :key="index"
  143. >
  144. <!-- 循环所有摄像头,根据摄像头个数分行分列 -->
  145. <!-- 分列 -->
  146. <u-col
  147. :span="24"
  148. v-for="(item, subindex) in row.list"
  149. :key="subindex"
  150. style="margin-top: 5px; margin-bottom: 5px"
  151. :style="'height:' + height"
  152. >
  153. <!-- 摄像头标题显示 -->
  154. <u-row>
  155. <view class="videotitle">
  156. <span>{{ item.name }}</span
  157. ><span v-if="item.netStatus == 0">【网络断开】</span>
  158. </view>
  159. </u-row>
  160. <!-- 摄像头展示 -->
  161. <view
  162. v-if="item.devicekind == 'flv'"
  163. style="width: 100%; height: 100%; text-align: center"
  164. >
  165. <video
  166. :id="'cameraElement' + item.id"
  167. muted
  168. autoplay
  169. controls
  170. width="100%"
  171. height="100%"
  172. ></video>
  173. </view>
  174. <!-- 海康控件展示 -->
  175. <iframe
  176. v-if="item.devicekind == 'hk'"
  177. ref="iframe"
  178. frameborder="0"
  179. scrolling="yes"
  180. style="
  181. z-index: -1;
  182. background-color: transparent;
  183. width: 100%;
  184. height: 100%;
  185. top: 0;
  186. left: 0;
  187. bottom: 0;
  188. "
  189. :src="item.showurl"
  190. ></iframe>
  191. </u-col>
  192. </u-row>
  193. </div>
  194. <div class="flcard">
  195. <div class="flex-container">
  196. <div
  197. class="itemback"
  198. v-for="(item, index) in typeList"
  199. :key="index"
  200. v-show="item.appShow == 1"
  201. >
  202. <div class="datacardtime" v-if="item.monitorcode == 'readTime'">
  203. <view
  204. class="demo-layout bg-purple-light"
  205. style="padding: 20rpx; color: #3787fe"
  206. >
  207. {{ readTime }}
  208. </view>
  209. </div>
  210. <div class="datacard" v-if="item.monitorcode !== 'readTime'">
  211. <div class="left-content">
  212. <view
  213. v-if="item.monitorcode == 'ndoortype'"
  214. class="demo-layout bg-purple-light"
  215. style="margin-top: 10rpx; color: #3787fe"
  216. >
  217. {{
  218. tableData[item.monitorcode] == "1"
  219. ? "行人"
  220. : tableData[item.monitorcode] == "2"
  221. ? "行车"
  222. : "-"
  223. }}
  224. </view>
  225. <view
  226. v-else-if="item.monitorcode == 'netStatus'"
  227. class="demo-layout bg-purple-light"
  228. style="margin-top: 10rpx; color: #3787fe"
  229. >
  230. {{ doorNetStatus == "1" ? "正常" : "异常" }}
  231. </view>
  232. <view
  233. v-else-if="item.monitorcode == 'warnFlag'"
  234. class="demo-layout bg-purple-light"
  235. style="margin-top: 10rpx; color: #3787fe"
  236. >
  237. {{ warnFlag == "1" ? "正常" : "异常" }}
  238. </view>
  239. <view
  240. v-else
  241. class="demo-layout bg-purple-light"
  242. style="margin-top: 10rpx; color: #3787fe"
  243. >
  244. {{
  245. tableData[item.monitorcode] == null ||
  246. tableData[item.monitorcode] == ""
  247. ? "-"
  248. : tableData[item.monitorcode]
  249. }}
  250. </view>
  251. <div class="spacer"></div>
  252. <!-- 间距 -->
  253. <view
  254. class="demo-layout bg-purple-light"
  255. style="color: #677799"
  256. >
  257. {{ item.des }}
  258. </view>
  259. </div>
  260. <div
  261. class="right-content"
  262. :style="{
  263. backgroundImage:
  264. item.monitorcode === 'frontRearDP' ||
  265. item.monitorcode === 'frontRearDifference'
  266. ? 'url(\'../../../../static/model/Pa.png\')'
  267. : item.monitorcode === 'sourcePressure'
  268. ? 'url(\'../../../../static/model/MPa.png\')'
  269. : item.monitorcode === 'frontGateOpen'
  270. ? 'url(\'../../../../static/model/doorNet.png\')'
  271. : item.monitorcode === 'rearGateOpen'
  272. ? 'url(\'../../../../static/model/doorNet.png\')'
  273. : item.monitorcode === 'midGateOpen'
  274. ? 'url(\'../../../../static/model/doorNet.png\')'
  275. : item.monitorcode === 'warnFlag'
  276. ? 'url(\'../../../../static/model/9432.png\')'
  277. : item.monitorcode === 'netStatus'
  278. ? 'url(\'../../../../static/model/9431.png\')'
  279. : item.monitorcode === 'm3'
  280. ? 'url(\'../../../../static/model/windM3.png\')'
  281. : item.monitorcode === 'fsectarea'
  282. ? 'url(\'../../../../static/model/duanArea.png\')'
  283. : item.monitorcode === 'incipientWindSpeed1' ||
  284. item.monitorcode === 'incipientWindSpeed2' ||
  285. item.monitorcode === 'incipientWindSpeed3' ||
  286. item.monitorcode === 'va'
  287. ? 'url(\'../../../../static/model/fengsu.png\')'
  288. : 'url(\'\')',
  289. backgroundSize: '100% 100%',
  290. }"
  291. ></div>
  292. </div>
  293. </div>
  294. </div>
  295. </div>
  296. </view>
  297. </view>
  298. <u-popup :show="show" mode="bottom" :safeAreaInsetBottom="false">
  299. <div class="containers">
  300. <view class="passWordName">
  301. <view
  302. class="title"
  303. style="margin-top: 15px"
  304. v-if="this.TabCur == 'window'"
  305. >风窗面积</view
  306. >
  307. <u-input
  308. class="passArea"
  309. style="margin-top: 15px; border-color: #2a94ff"
  310. v-model="windowArea"
  311. type="text"
  312. v-if="this.TabCur == 'window'"
  313. ></u-input>
  314. </view>
  315. <view class="passWordInput">
  316. <view style="margin-top: 15px" class="title">输入密码</view>
  317. <u-input
  318. style="margin-top: 15px; border-color: #2a94ff"
  319. v-model="password"
  320. type="password"
  321. ></u-input
  322. ></view>
  323. </div>
  324. <view class="btns">
  325. <u-button
  326. style="margin: 20px"
  327. type="primary"
  328. @click="confirmPassword()"
  329. color="linear-gradient(to right, rgb(53, 138, 254), rgb(38, 171, 244))"
  330. >确认</u-button
  331. >
  332. <u-button
  333. style="margin: 20px"
  334. type="primary"
  335. :plain="true"
  336. @click="cancelPassword()"
  337. >取消</u-button
  338. >
  339. </view>
  340. </u-popup>
  341. </view>
  342. </template>
  343. <script>
  344. import api from "@/api/api";
  345. import initDictOptions from "@/common/util/dictUtil.js";
  346. import doorAnimate from "../doorAnimate/doorAnimate.vue";
  347. import windowAnimate from "../windowAnimate/windowAnimate.vue";
  348. import windrectAnimate from "../windrectAnimate/windrectAnimate.vue";
  349. import fanlocalAnimate from "../fanlocalAnimate/fanlocalAnimate2.vue";
  350. import fanmainAnimate from "../fanmainAnimate/fanmainAnimate.vue";
  351. import flvjs from "flv.js";
  352. export default {
  353. data() {
  354. return {
  355. tableData: [], //监测数据
  356. typeList: [], //展示字段
  357. itemId: "", // 初始化 itemId
  358. name: "", // 初始化 name
  359. deviceid: "", //初始化设备id
  360. TabCur: "",
  361. checked: [],
  362. backPic0: "url(/static/topnavbar0.png)",
  363. backPic: "url(/static/topnavbar.png)",
  364. frontAngle: "", //风窗打开角度
  365. nwindownum: "", //风窗道数
  366. ndoorcount: "", //风门道数
  367. deviceType: "", //设备类型
  368. show: false, //密码弹窗是否显示
  369. password: "", //控制设备密码
  370. paramcode: "", //控制字段
  371. height: "200px",
  372. popupStyle: {
  373. // 弹窗样式
  374. "background-color": "#fff",
  375. padding: "20px",
  376. "box-shadow": "0 2px 4px rgba(0, 0, 0, 0.1)",
  377. },
  378. frontGateStatus: "", //前门状态
  379. rearGateStatus: "", //后门状态
  380. midGateStatus: "", //状态
  381. doorNetStatus: "", //风门通信状态
  382. warnFlag: "", //风门报警
  383. readTime: "", //时间
  384. windowAngle: 0, //前窗打开角度
  385. windowAngle1: 0, //后窗打开角度
  386. windowArea: "", //风窗面积设定值
  387. viedeoUrl: "", //监控url
  388. sign: "",
  389. title: "测风设备",
  390. fan1State: "",
  391. fan2State: "",
  392. deviceid: "", //ID
  393. cameralist: [], //摄像数据
  394. rows: [], //分行
  395. flvPlayer: [],
  396. num: 1, //摄像头个数
  397. columnNum: 1, //列数
  398. columSpan: 24, //列块
  399. cameraType: "",
  400. };
  401. },
  402. onLoad(query) {
  403. //保存id到 data 中 可以在整个页面中使用
  404. this.itemId = query.id;
  405. this.name = query.name;
  406. this.TabCur = query.type;
  407. this.ndoorcount = 2;
  408. },
  409. components: {
  410. doorAnimate,
  411. windowAnimate,
  412. windrectAnimate,
  413. fanlocalAnimate,
  414. fanmainAnimate,
  415. },
  416. created() {
  417. this.getShowList(this.TabCur);
  418. this.getDeviceInfo(this.itemId);
  419. this.getVideoUrlById(this.itemId);
  420. },
  421. mounted() {
  422. this.startTimer();
  423. },
  424. methods: {
  425. startTimer() {
  426. this.timer = setInterval(() => {
  427. // 执行定时任务
  428. this.getDeviceInfo(this.itemId);
  429. }, 5000);
  430. },
  431. stopTimer() {
  432. // 停止定时器
  433. clearInterval(this.timer);
  434. },
  435. // 返回上一个页面
  436. backPage() {
  437. this.$destroy();
  438. uni.navigateBack({
  439. delta: 1,
  440. });
  441. },
  442. //获取app展示字段数据
  443. getShowList(type) {
  444. const params = {
  445. devicekind: type,
  446. pagetype: "detail",
  447. pageNo: 1,
  448. pageSize: 100,
  449. };
  450. new Promise((resolve, reject) => {
  451. api
  452. .getShowColumList(params)
  453. .then((response) => {
  454. if (response.data.code == 200) {
  455. this.typeList = response.data.result.records;
  456. } else {
  457. resolve(response);
  458. }
  459. })
  460. .catch((error) => {
  461. reject(error);
  462. });
  463. });
  464. },
  465. //获取详情数据
  466. getDeviceInfo(ID) {
  467. let IDString = String(ID); // 将 ID 转换为字符串
  468. new Promise((resolve, reject) => {
  469. api
  470. .getDeviceMonitor({ devicetype: this.TabCur, ids: IDString })
  471. .then((response) => {
  472. if (
  473. response.data.code == 200 &&
  474. response.data.result.msgTxt[0].datalist.length > 0
  475. ) {
  476. var result = response.data.result.msgTxt[0].datalist[0];
  477. this.tableData = result.readData;
  478. if (this.tableData.frontGateOpen == "1") {
  479. this.tableData.frontGateOpen = "打开";
  480. } else {
  481. this.tableData.frontGateOpen = "关闭";
  482. }
  483. if (this.tableData.midGateOpen == "1") {
  484. this.tableData.midGateOpen = "打开";
  485. } else {
  486. this.tableData.midGateOpen = "关闭";
  487. }
  488. if (this.tableData.rearGateOpen == "1") {
  489. this.tableData.rearGateOpen = "打开";
  490. } else {
  491. this.tableData.rearGateOpen = "关闭";
  492. }
  493. this.fan1State = result.readData.Fan1StartStatus;
  494. this.fan2State = result.readData.Fan2StartStatus;
  495. this.nwindownum = result.nwindownum;
  496. this.ndoorcount = result.ndoorcount;
  497. this.deviceType = result.deviceType;
  498. this.state = result.readData.sign;
  499. this.frontGateStatus = this.tableData.frontGateOpen;
  500. this.midGateStatus = this.tableData.midGateOpen;
  501. this.rearGateStatus = this.tableData.rearGateOpen;
  502. this.doorNetStatus = result.netStatus;
  503. this.warnFlag = result.warnLevel_str;
  504. this.readTime = result.readTime;
  505. var maxarea = result.maxarea;
  506. this.windowAngle =
  507. (this.tableData.forntArea / maxarea) * 100 * 0.9;
  508. this.windowAngle1 =
  509. (this.tableData.rearArea / maxarea) * 100 * 0.9;
  510. this.deviceid = result.deviceID;
  511. this.$forceUpdate();
  512. } else {
  513. resolve(response);
  514. }
  515. })
  516. .catch((error) => {
  517. reject(error);
  518. });
  519. });
  520. },
  521. //获取监控URL 通过ID获取
  522. getVideoUrlById(ID) {
  523. let IDString = String(ID); // 将 ID 转换为字符串
  524. new Promise((resolve, reject) => {
  525. api
  526. .getCameraById({ deviceid: IDString })
  527. .then((response) => {
  528. if (response.data.code == 200) {
  529. if (response.data.result.records.length > 0) {
  530. this.cameralist = response.data.result.records;
  531. this.initData();
  532. }
  533. } else {
  534. resolve(response);
  535. }
  536. })
  537. .catch((error) => {
  538. reject(error);
  539. });
  540. });
  541. },
  542. initData() {
  543. this.num = this.cameralist.length;
  544. // 根据总数量 设置行数、列数
  545. // 分行分列
  546. this.setRows();
  547. // if (this.cameraType == "flv") {
  548. if (this.cameralist.length > 0) {
  549. setTimeout(() => {
  550. this.cameralist.forEach((element) => {
  551. if (element.netStatus == 1)
  552. // 根据id设置每个播放摄像头的地址
  553. this.setVideoUrl(element, element.id);
  554. });
  555. }, 1000);
  556. // }
  557. }
  558. // }
  559. },
  560. // 根据id设置每个播放摄像头的地址
  561. setVideoUrl(element, id) {
  562. if (flvjs.isSupported()) {
  563. var videourl = element.ip;
  564. if (videourl == null || videourl.indexOf("http") == -1)
  565. videourl = configUrl.getCameraFLV() + id + ".flv";
  566. var videoElement = document.getElementById("cameraElement" + id);
  567. // 控件设置地址信息
  568. var vdo = flvjs.createPlayer({
  569. type: "flv",
  570. url: videourl,
  571. });
  572. // 控件绑定
  573. vdo.attachMediaElement(videoElement);
  574. vdo.load();
  575. // 播放
  576. vdo.play();
  577. this.flvPlayer.push(vdo);
  578. }
  579. },
  580. // 每行摄像头分列
  581. setRows() {
  582. this.rows = [];
  583. var index = 0;
  584. // 循环行
  585. for (var i = 0; i < this.cameralist.length; i++) {
  586. // 一行
  587. var row1 = {};
  588. var rowlist = [];
  589. // 根据摄像头信息设置每个摄像头的访问地址
  590. if (index == 0)
  591. this.cameralist[i].showurl =
  592. this.cameralist[i].showurl + "&checkComponent=1";
  593. // 每行摄像头信息
  594. rowlist.push(this.cameralist[i]);
  595. index++;
  596. row1.index = i;
  597. row1.list = rowlist;
  598. // 摄像头行数
  599. this.rows.push(row1);
  600. console.log(this.rows, "1111111111111111");
  601. }
  602. },
  603. //设备控制
  604. ctrlDevice(pass) {
  605. let IDString = String(this.itemId); // 将 ID 转换为字符串
  606. const params = {
  607. deviceid: IDString,
  608. devicetype: this.deviceType,
  609. paramcode: this.paramcode,
  610. password: pass,
  611. value: this.windowArea,
  612. };
  613. new Promise((resolve, reject) => {
  614. api
  615. .controlDevice(params)
  616. .then((response) => {
  617. if (response.data.code == 200) {
  618. this.getDeviceInfo(IDString);
  619. // console.log("操作成功");
  620. } else {
  621. resolve(response);
  622. }
  623. })
  624. .catch((error) => {
  625. reject(error);
  626. });
  627. });
  628. },
  629. // 显示密码输入弹窗
  630. showPasswordDialog(controlCode) {
  631. this.paramcode = controlCode;
  632. this.show = true;
  633. },
  634. // 取消密码输入
  635. cancelPassword() {
  636. this.show = false;
  637. },
  638. confirmPassword() {
  639. this.ctrlDevice(this.password);
  640. // 发起请求后关闭密码输入弹窗
  641. this.show = false;
  642. },
  643. },
  644. destroyed() {
  645. // 停止定时器
  646. this.stopTimer();
  647. // 控件清除缓存
  648. this.flvPlayer.forEach((element) => {
  649. element.pause();
  650. element.unload();
  651. element.detachMediaElement();
  652. element.destroy();
  653. element = null;
  654. });
  655. },
  656. };
  657. </script>
  658. <style lang="scss" scoped>
  659. .videotitle {
  660. z-index: 2;
  661. position: absolute;
  662. top: 0px;
  663. top: 10px;
  664. right: 10px;
  665. font-size: 16px;
  666. }
  667. .top-nav {
  668. background-image: url(../../../../static/topnavbar.png);
  669. background-size: cover; /* 背景图片大小适应 */
  670. height: 100%;
  671. }
  672. .top-nav2 {
  673. background-color: #ffffff;
  674. }
  675. .main {
  676. margin-top: 80px;
  677. }
  678. .container {
  679. display: flex;
  680. flex-direction: column;
  681. }
  682. .button-grid {
  683. display: grid;
  684. grid-template-columns: repeat(4, 1fr);
  685. gap: 5px; /* 可以根据需要调整行列之间的间距 */
  686. }
  687. .flcard {
  688. padding: 20rpx;
  689. background-color: #ffffff;
  690. margin-bottom: 5rpx;
  691. }
  692. .additional-div {
  693. grid-column: span 2; /* 让附加内容跨越三列 */
  694. display: flex;
  695. align-items: center;
  696. }
  697. .checkbox-group {
  698. margin-left: 10px; /* 可以根据需要调整间距 */
  699. }
  700. .card {
  701. background-color: #ffffff;
  702. margin: auto;
  703. margin-top: 20rpx;
  704. width: 90%;
  705. height: 280rpx;
  706. border: 1rpx solid #000000;
  707. border-radius: 20rpx;
  708. }
  709. .flex-containe {
  710. display: flex;
  711. flex-direction: row;
  712. flex-wrap: wrap;
  713. }
  714. .itemback {
  715. flex: 0 0 calc(33.33% - 10px); /* 使用calc函数计算每个项目的宽度,减去间距 */
  716. margin: 5px; /* 间距设置为5px */
  717. }
  718. .datacardtime {
  719. display: flex;
  720. width: 100%;
  721. flex: 1;
  722. margin: 1%;
  723. float: left;
  724. height: 50rpx;
  725. text-align: center;
  726. background: linear-gradient(
  727. to right,
  728. rgba(55, 135, 254, 0.08),
  729. rgba(4, 184, 255, 0.08),
  730. rgba(60, 161, 237, 0.08)
  731. );
  732. }
  733. .datacard {
  734. display: flex;
  735. width: 48%;
  736. flex: 1;
  737. margin: 1%;
  738. float: left;
  739. height: 100rpx;
  740. text-align: center;
  741. background: linear-gradient(
  742. to right,
  743. rgba(55, 135, 254, 0.08),
  744. rgba(4, 184, 255, 0.08),
  745. rgba(60, 161, 237, 0.08)
  746. );
  747. }
  748. .left-content {
  749. width: 50%;
  750. display: flex;
  751. flex-direction: column;
  752. }
  753. .spacer {
  754. height: 10rpx;
  755. }
  756. .right-content {
  757. width: 50%; /* 右侧内容占据50%宽度 */
  758. background-image: url(../../../../static/model/Pa.png);
  759. background-size: 100% 125%;
  760. }
  761. /*风窗样式*/
  762. div.autowindow_new {
  763. width: 200px;
  764. height: 200px;
  765. background-image: url(../../../../static/window/window-bk.png);
  766. background-size: 100% 100%;
  767. perspective: 800px;
  768. }
  769. /*风窗1 2 3 4*/
  770. div.window_new_1 {
  771. margin-top: 12px;
  772. margin-left: 15px;
  773. width: 170px;
  774. height: 30px;
  775. background-color: crimson;
  776. box-sizing: border-box;
  777. float: left;
  778. z-index: 1;
  779. /* transition: all 2s; */
  780. background-image: url(../../../../static/window/window_new1.png);
  781. background-size: 100% 100%;
  782. }
  783. div.window_new_2 {
  784. margin-top: 2px;
  785. margin-left: 15px;
  786. width: 170px;
  787. height: 29px;
  788. background-color: crimson;
  789. box-sizing: border-box;
  790. float: left;
  791. z-index: 1;
  792. /* transition: all 2s; */
  793. background-image: url(../../../../static/window/window_new1.png);
  794. background-size: 100% 100%;
  795. }
  796. div.window_new_3 {
  797. margin-top: 2px;
  798. margin-left: 15px;
  799. width: 170px;
  800. height: 29px;
  801. background-color: crimson;
  802. box-sizing: border-box;
  803. float: left;
  804. z-index: 1;
  805. /* transition: all 2s; */
  806. background-image: url(../../../../static/window/window_new1.png);
  807. background-size: 100% 100%;
  808. }
  809. div.window_new_4 {
  810. margin-top: 2px;
  811. margin-left: 15px;
  812. width: 170px;
  813. height: 29px;
  814. background-color: crimson;
  815. box-sizing: border-box;
  816. float: left;
  817. z-index: 1;
  818. /* transition: all 2s; */
  819. background-image: url(../../../../static/window/window_new1.png);
  820. background-size: 100% 100%;
  821. }
  822. div.window_new_5 {
  823. margin-top: 2px;
  824. margin-left: 15px;
  825. width: 170px;
  826. height: 29px;
  827. background-color: crimson;
  828. box-sizing: border-box;
  829. float: left;
  830. z-index: 1;
  831. /* transition: all 2s; */
  832. background-image: url(../../../../static/window/window_new1.png);
  833. background-size: 100% 100%;
  834. }
  835. div.window_new_1 {
  836. transition: all 2s ease;
  837. transform-origin: center center;
  838. }
  839. div.window_new_2 {
  840. transition: all 2s ease;
  841. transform-origin: center center;
  842. }
  843. div.window_new_3 {
  844. transition: all 2s ease;
  845. transform-origin: center center;
  846. }
  847. div.window_new_4 {
  848. transition: all 2s ease;
  849. transform-origin: center center;
  850. }
  851. div.window_new_5 {
  852. transition: all 2s ease;
  853. transform-origin: center center;
  854. }
  855. .btns {
  856. display: flex;
  857. }
  858. .containers {
  859. background-color: #fff;
  860. }
  861. .passWordName {
  862. margin: 20px;
  863. display: flex;
  864. flex-direction: row;
  865. justify-content: space-around;
  866. }
  867. .title {
  868. margin-right: 20px;
  869. line-height: 40px;
  870. }
  871. .passWordInput {
  872. margin: 20px;
  873. display: flex;
  874. flex-direction: row;
  875. justify-content: space-around;
  876. }
  877. .passArea {
  878. border-color: red;
  879. }
  880. </style>