sopmLook.vue 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494
  1. <template>
  2. <div class="newOperations">
  3. <!-- newOperations盒子开始-->
  4. <div class="left">
  5. <!-- 车间 -->
  6. <keep-alive>
  7. <SopLeft
  8. v-show="this.activeName == 'first' || this.activeName == 'third'"
  9. @product-line-selected="handleProductLineSelected"
  10. @work-shop-selected="handleWorkshopSelected"
  11. :sopProps="sopProps"
  12. ></SopLeft>
  13. </keep-alive>
  14. <!-- 隔离点 style="position: relative;z-index:0"-->
  15. <!-- <IsolationLeftVue
  16. v-show="this.activeName == 'second'"
  17. :points="points"
  18. @selection-changed="handleSelectPoint"
  19. ></IsolationLeftVue> -->
  20. <IsolationLeftVue
  21. :points="points"
  22. @selection-changed="handleSelectPoint"
  23. ></IsolationLeftVue>
  24. </div>
  25. <!-- 作业区域 -->
  26. <div class="lefttree">
  27. <el-card class="lefttree-card" v-show="this.showWorkEare == true">
  28. <b class="title">作业区域</b>
  29. <div class="head-container">
  30. <el-input
  31. v-model="workareaName"
  32. placeholder="请输入作业区域"
  33. clearable
  34. size="small"
  35. prefix-icon="el-icon-search"
  36. style="margin-bottom: 20px"
  37. @input="handleInputChange"
  38. />
  39. </div>
  40. <div class="head-container">
  41. <el-tree
  42. :data="deptOptions"
  43. :props="defaultProps"
  44. :expand-on-click-node="false"
  45. :filter-node-method="filterNode"
  46. ref="tree"
  47. node-key="id"
  48. default-expand-all
  49. @node-click="handleNodeClick"
  50. highlight-current
  51. />
  52. </div>
  53. </el-card>
  54. <!-- 收起 -->
  55. <el-tooltip
  56. class="item"
  57. effect="dark"
  58. content="收起作业区域内容"
  59. placement="top-start"
  60. >
  61. <el-button
  62. v-no-more-click
  63. type="primary"
  64. icon="el-icon-s-fold"
  65. class="btnwork"
  66. v-show="this.showWorkEare == true"
  67. @click="openWorkEare"
  68. ></el-button>
  69. </el-tooltip>
  70. <!-- 打开 -->
  71. <el-tooltip
  72. class="item"
  73. effect="dark"
  74. content="展开作业区域内容"
  75. placement="top-start"
  76. >
  77. <el-button
  78. v-no-more-click
  79. type="primary"
  80. icon="el-icon-s-unfold"
  81. class="btnwork"
  82. v-show="this.showWorkEare == false"
  83. @click="closeWorkEare"
  84. ></el-button>
  85. </el-tooltip>
  86. </div>
  87. <div class="right">
  88. <div class="right_top">
  89. <el-card class="box-card">
  90. <div slot="header" class="clearfix">
  91. <span style="font-size: 18px">{{ this.getSopTitle }}</span>
  92. <span
  93. style="
  94. padding: 1px 10px 1px 16%;
  95. font-size: 22px;
  96. cursor: pointer;
  97. "
  98. type="text"
  99. @click="goBack"
  100. >×</span
  101. >
  102. <el-tooltip
  103. content="开启人员配置"
  104. placement="top"
  105. style="float: right; margin-top: 3px; display: none"
  106. >
  107. <el-switch
  108. v-model="openStaffing"
  109. active-color="#13ce66"
  110. active-text=""
  111. @change="handleOpenStaffing(openStaffing)"
  112. >
  113. </el-switch>
  114. </el-tooltip>
  115. </div>
  116. <div class="text item">
  117. <!-- 新增作业票信息-->
  118. <b class="title">基本信息</b>
  119. <el-form ref="form" :model="form" label-width="70px">
  120. <el-form-item label="SOP名称" prop="sopName">
  121. <el-input
  122. :disabled="this.getSopLook"
  123. v-model="form.sopName"
  124. placeholder="请输入SOP名称"
  125. style="width: 100%"
  126. />
  127. </el-form-item>
  128. <el-row>
  129. <el-col :span="16">
  130. <el-form-item label="SOP编号" prop="sopCode">
  131. <el-input
  132. :disabled="this.getSopLook"
  133. v-model="form.sopCode"
  134. placeholder="请输入SOP编号"
  135. style="width: 100%"
  136. />
  137. </el-form-item>
  138. </el-col>
  139. <el-col :span="8">
  140. <el-form-item label-width="80">
  141. <el-switch
  142. :disabled="this.getSopLook"
  143. v-model="autoGenFlag"
  144. active-color="#13ce66"
  145. active-text="自动生成"
  146. @change="handleAutoGenChange(autoGenFlag)"
  147. >
  148. </el-switch>
  149. </el-form-item>
  150. </el-col>
  151. </el-row>
  152. <el-form-item label="SOP类型" prop="sopType">
  153. <el-select
  154. :disabled="this.getSopLook"
  155. v-model="form.sopType"
  156. placeholder="请选择SOP类型"
  157. clearable
  158. style="width: 100%"
  159. >
  160. <el-option
  161. v-for="dict in dict.type.sop_type"
  162. :key="dict.value"
  163. :label="dict.label"
  164. :value="dict.value"
  165. />
  166. </el-select>
  167. </el-form-item>
  168. <el-form-item label="SOP内容" prop="sopContent">
  169. <el-input
  170. :disabled="this.getSopLook"
  171. type="textarea"
  172. v-model="form.sopContent"
  173. :rows="3"
  174. ></el-input>
  175. </el-form-item>
  176. </el-form>
  177. <!-- 隔离点信息-->
  178. <b class="title">隔离点信息</b>
  179. <el-form ref="form" :model="form" label-width="90px">
  180. <!-- <el-form-item label="车间名称" prop="workshopName">-->
  181. <!-- <el-input-->
  182. <!-- v-model="form.workshopName"-->
  183. <!-- style="width: 100%"-->
  184. <!-- disabled-->
  185. <!-- />-->
  186. <!-- </el-form-item>-->
  187. <!-- <el-form-item label="作业区域" prop="workline">
  188. <el-input
  189. v-model="form.workline"
  190. style="width: 100%"
  191. disabled
  192. />
  193. </el-form-item> -->
  194. <div class="text item">
  195. <!-- <p style="color: #606266; font-weight: 600; font-size: 14px">
  196. 已选隔离点
  197. </p> -->
  198. <el-table
  199. :data="tableData"
  200. stripe
  201. height="260"
  202. style="width: 100%"
  203. id="table-key"
  204. row-key="id"
  205. >
  206. <el-table-column prop="pointName" label="隔离点" width="80">
  207. <template slot-scope="scope">
  208. <span style="color: #2a87ff">{{
  209. scope.row.pointName
  210. }}</span>
  211. </template>
  212. </el-table-column>
  213. <el-table-column prop="pointType" label="隔离点类型">
  214. <template slot-scope="scope">
  215. {{ scope.row.pointType }}
  216. </template>
  217. </el-table-column>
  218. <el-table-column
  219. prop="powerType"
  220. label="危险能量类型"
  221. width="100"
  222. >
  223. <template slot-scope="scope">
  224. {{ scope.row.powerType }}
  225. </template>
  226. </el-table-column>
  227. <el-table-column
  228. prop="prePointId"
  229. label="前置隔离点"
  230. >
  231. <template slot-scope="scope">
  232. <el-select
  233. size="mini"
  234. v-model="scope.row.prePointId"
  235. @change="prePointIdChange(scope.row)"
  236. @visible-change="onDropdownVisibleChange(scope.row)"
  237. disabled
  238. >
  239. <el-option
  240. v-for="item in prePointIdOptions"
  241. :key="item.pointId"
  242. :label="item.pointName"
  243. :value="item.pointId"
  244. >
  245. </el-option>
  246. </el-select>
  247. </template>
  248. </el-table-column>
  249. </el-table>
  250. </div>
  251. </el-form>
  252. <!--人员选择-->
  253. <b class="title" v-if="openStaffing">人员信息</b>
  254. <el-form
  255. ref="form"
  256. :model="form"
  257. label-width="70px"
  258. v-if="openStaffing"
  259. >
  260. <el-form-item label="上锁人" prop="locker">
  261. <el-select
  262. :disabled="this.getSopLook"
  263. v-model="form.locker"
  264. placeholder="上锁人"
  265. clearable
  266. style="width: 100%"
  267. @change="handlelockerChage"
  268. >
  269. <el-option
  270. v-for="dict in this.listLockerOption"
  271. :key="dict.value"
  272. :label="dict.label"
  273. :value="dict.value"
  274. />
  275. </el-select>
  276. </el-form-item>
  277. <el-form-item label="共锁人" prop="coLocker">
  278. <el-button
  279. v-no-more-click
  280. type="primary"
  281. @click="addInside"
  282. class="gsr"
  283. size="mini"
  284. disabled
  285. >添加内部人员
  286. </el-button>
  287. <el-button
  288. v-no-more-click
  289. type="primary"
  290. @click="addOutside"
  291. size="mini"
  292. disabled
  293. >添加外部人员
  294. </el-button>
  295. </el-form-item>
  296. <div class="text item">
  297. <el-table
  298. :data="sortedTicketUserDTOList"
  299. stripe
  300. height="300"
  301. style="width: 100%"
  302. >
  303. <el-table-column prop="userId" label="序号" width="50">
  304. </el-table-column>
  305. <el-table-column prop="userName" label="共锁人" width="120">
  306. <template slot-scope="scope">
  307. <span style="color: #2a87ff">{{
  308. scope.row.userName
  309. }}</span>
  310. </template>
  311. </el-table-column>
  312. <el-table-column prop="userType" label="共锁人来源">
  313. <template slot-scope="scope">
  314. <span>{{
  315. scope.row.userType == "0" ? "内部" : "外部"
  316. }}</span>
  317. </template>
  318. </el-table-column>
  319. <el-table-column label="" width="80">
  320. <template slot-scope="scope">
  321. <el-button
  322. v-no-more-click
  323. @click.native.prevent="
  324. deleteRow(scope.$index, sortedTicketUserDTOList)
  325. "
  326. type="text"
  327. size="small"
  328. disabled
  329. >
  330. 移除
  331. </el-button>
  332. </template>
  333. </el-table-column>
  334. </el-table>
  335. </div>
  336. </el-form>
  337. </div>
  338. </el-card>
  339. </div>
  340. </div>
  341. <!-- newSop盒子结束-->
  342. <!-- 添加或修改设备维修单对话框 -->
  343. <el-dialog
  344. :visible.sync="open"
  345. width="450px"
  346. append-to-body
  347. style="margin-top: 13%"
  348. >
  349. <div slot="title" class="dialog-title">
  350. <i></i>
  351. <span class="title">{{ title }}</span>
  352. </div>
  353. <el-form ref="dialogForm" :model="dialogForm" label-width="70px">
  354. <el-form-item label="选择人员" prop="nickName" v-if="insideMumber">
  355. <el-select
  356. v-model="dialogForm.nickName"
  357. placeholder="请选择人员"
  358. clearable
  359. style="width: 100%"
  360. multiple
  361. @change="changeInsideUser"
  362. >
  363. <el-option
  364. v-for="dict in this.listCoLockerOption"
  365. :key="dict.value"
  366. :label="dict.label"
  367. :value="dict.value"
  368. />
  369. </el-select>
  370. </el-form-item>
  371. <el-form-item label="人员ID" prop="username" v-if="outsideMumber">
  372. <el-row>
  373. <el-col :span="16">
  374. <el-input
  375. v-model="dialogForm.username"
  376. placeholder="请输入人员ID"
  377. clearable
  378. style="width: 80%"
  379. @change="outSideUserInput"
  380. />
  381. </el-col>
  382. <el-col :span="4">
  383. <el-button
  384. v-no-more-click
  385. type="primary"
  386. @click="insertOutSideTable"
  387. >添加</el-button
  388. >
  389. </el-col>
  390. </el-row>
  391. </el-form-item>
  392. <el-row>
  393. <el-table
  394. :data="OutSideUserTableData"
  395. stripe
  396. height="200"
  397. v-if="outsideMumber"
  398. >
  399. <el-table-column prop="userId" label="序号"> </el-table-column>
  400. <el-table-column prop="userName" label="人员ID">
  401. <template slot-scope="scope">
  402. <span style="color: #2a87ff">{{ scope.row.userName }}</span>
  403. </template>
  404. </el-table-column>
  405. <el-table-column label="操作" width="80">
  406. <template slot-scope="scope">
  407. <el-button
  408. v-no-more-click
  409. @click.native.prevent="
  410. deleteRow(scope.$index, OutSideUserTableData)
  411. "
  412. type="text"
  413. size="small"
  414. >
  415. 移除
  416. </el-button>
  417. </template>
  418. </el-table-column>
  419. </el-table>
  420. </el-row>
  421. </el-form>
  422. <div slot="footer" class="dialog-footer">
  423. <!-- 内部人员确认-->
  424. <el-button
  425. v-no-more-click
  426. type="primary"
  427. @click="cancel"
  428. v-if="insideMumber"
  429. >确认</el-button
  430. >
  431. <!-- 外部人员确认-->
  432. <el-button
  433. v-no-more-click
  434. type="primary"
  435. @click="outSideDialogConfirm"
  436. v-if="outsideMumber"
  437. >确认</el-button
  438. >
  439. <el-button v-no-more-click @click="cancel">取 消</el-button>
  440. </div>
  441. </el-dialog>
  442. <!-- 加载 -->
  443. <div class="loadbox" v-if="isVisible">
  444. <h5>加载中</h5>
  445. <i class="el-icon-loading"></i>
  446. </div>
  447. </div>
  448. </template>
  449. <script>
  450. import IsolationLeftVue from "@/components/separationPoint/index.vue";
  451. import SopLeft from "@/components/separationPoint/workshop.vue";
  452. import { genCode } from "@/api/system/autocode/rule";
  453. import {
  454. addinsertIsSop,
  455. updateIsSop,
  456. selectIsSopById,
  457. SopUser,
  458. } from "@/api/mes/sop/sopindex-booz";
  459. import { mapActions, mapGetters } from "vuex";
  460. import { listWorkarea } from "@/api/mes/wa/workarea";
  461. import "@riophae/vue-treeselect/dist/vue-treeselect.css";
  462. import Treeselect from "@riophae/vue-treeselect";
  463. export default {
  464. name: "addView",
  465. dicts: ["power_type", "point_type", "sop_type", "job_user_role"],
  466. props: {
  467. sopProps: {
  468. type: Array,
  469. default: () => [],
  470. },
  471. jobProps: {
  472. type: Array,
  473. default: () => [],
  474. },
  475. },
  476. components: {
  477. SopLeft,
  478. IsolationLeftVue,
  479. Treeselect,
  480. },
  481. data() {
  482. return {
  483. //自动生成编码
  484. autoGenFlag: false,
  485. activeName: "second",
  486. form: {
  487. sopName: "",
  488. sopCode: "",
  489. SOPType: "",
  490. workshopName: "", //车间名称
  491. workline: "", //区域
  492. workareaName: "",
  493. spoint: [], //已选隔离点
  494. prePointId: [], //已选隔离点的前置节点Id
  495. locker: "", //上锁人
  496. coLocker: "", //共锁人
  497. pointDetailVOList: [], //隔离点数据
  498. ticketUserDTOList: [
  499. // {
  500. // userId: '',
  501. // userName: '',
  502. // userRole: '',//作业票角色 暂时不传递 内部人还是外部人
  503. // userType: ''//用户类型 上锁人或共锁人
  504. // }
  505. ], //所选择的用户
  506. },
  507. // 部门树选项
  508. deptOptions: undefined,
  509. defaultProps: {
  510. children: "children",
  511. label: "label",
  512. },
  513. pickerOptions: {
  514. shortcuts: [
  515. {
  516. text: "今天",
  517. onClick(picker) {
  518. picker.$emit("pick", new Date());
  519. },
  520. },
  521. {
  522. text: "昨天",
  523. onClick(picker) {
  524. const date = new Date();
  525. date.setTime(date.getTime() - 3600 * 1000 * 24);
  526. picker.$emit("pick", date);
  527. },
  528. },
  529. {
  530. text: "一周前",
  531. onClick(picker) {
  532. const date = new Date();
  533. date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
  534. picker.$emit("pick", date);
  535. },
  536. },
  537. ],
  538. },
  539. // 右侧底部已选隔离点
  540. tableData: null,
  541. orderTableData:[],//排序
  542. points: null, //车间逆向传递拿到的隔离点数据
  543. emitWorkShop: null, //车间逆向传递拿到车间相关数据
  544. emitworklineId: null, //生产线逆向传递拿到数据
  545. sopProps: [], //正传递
  546. worklineMap: "",
  547. prePointIdOptions: [], //前置节点的下拉选项
  548. initprePointIdOptions: [], //前置节点初始化数据选项
  549. prePointId: null, //回显选中的前置节点id
  550. relations: [], //维护父子关系的前置节点
  551. openStaffing: null,
  552. newticketUserDTOList: [], //为了上锁人单独传递数据
  553. // 弹框中显示的form表单内容
  554. insideMumber: false,
  555. outsideMumber: false,
  556. // 是否显示弹出层
  557. open: false,
  558. // 弹出层标题
  559. title: "",
  560. dialogForm: {
  561. nickName: "",
  562. username: "",
  563. },
  564. listLockerOption: null, //上锁人下拉数据
  565. listCoLockerOption: null, //共锁人下拉数据
  566. OutSideUserTableData: [], //添加外部人员多个表格
  567. nextUserId: 0, //新增外部人员表格序号自定义
  568. showWorkEare: true, //作业区域是否展示
  569. isVisible: true, // 控制盒子显示状态
  570. };
  571. },
  572. mounted() {
  573. // // 5秒后隐藏盒子
  574. setTimeout(() => {
  575. this.isVisible = false;
  576. }, 2000);
  577. this.getTreeselect(); //获取作业区域下拉
  578. this.handleOpenStaffing();
  579. if (this.$route.query.sopId !== "null") {
  580. // console.log(this.$route.query.sopId, "接受路由参数");
  581. this.getSopInfo();
  582. if (this.getSopLook) {
  583. this.setSopTitle("查看SOP");
  584. } else {
  585. this.setSopTitle("编辑SOP");
  586. }
  587. } else {
  588. this.setSelectSopPoints([]);
  589. this.setPointTableData([]);
  590. this.setSopTitle("新建SOP");
  591. }
  592. },
  593. computed: {
  594. ...mapGetters("sopSelectPoints", [
  595. "getSopTitle",
  596. "getSopLook",
  597. "getMapData",
  598. ]),
  599. // 排序 ticketUserDTOList,将 userRole 为 0 的选项放在前面
  600. sortedTicketUserDTOList() {
  601. return this.form.ticketUserDTOList.sort(
  602. (a, b) => Number(a.userRole) - Number(b.userRole)
  603. );
  604. },
  605. },
  606. methods: {
  607. ...mapActions("sopSelectPoints", [
  608. "setSelectSopPoints",
  609. "setPointTableData",
  610. "setSopEdit",
  611. "setSopTitle",
  612. ]),
  613. // 作业区域打开关闭
  614. openWorkEare() {
  615. this.showWorkEare = false;
  616. },
  617. closeWorkEare() {
  618. this.showWorkEare = true;
  619. },
  620. /** 查询作业区域下拉树结构 */
  621. getTreeselect() {
  622. const data = {
  623. current: 1,
  624. size: -1,
  625. };
  626. listWorkarea(data).then((response) => {
  627. // console.log(response.data.records, '作业区域下拉树形结构');
  628. // 转换为树形结构
  629. this.deptOptions = this.transformToTree(response.data.records);
  630. // console.log(this.deptOptions, 'deptOptions')
  631. // 使用递归函数查找匹配的节点
  632. console.log(this.workareaName, "name");
  633. const selectedTreeNode = this.findNodeById(
  634. this.deptOptions,
  635. this.workareaName
  636. );
  637. // 调用 handleNodeClick 方法
  638. if (selectedTreeNode) {
  639. this.handleNodeClick(selectedTreeNode);
  640. } else {
  641. console.log("未找到匹配的节点");
  642. }
  643. });
  644. },
  645. // 深层次遍历
  646. findNodeById(nodes, targetId) {
  647. for (let i = 0; i < nodes.length; i++) {
  648. const node = nodes[i];
  649. if (node.id === targetId) {
  650. return node;
  651. }
  652. if (node.children && node.children.length > 0) {
  653. const foundNode = this.findNodeById(node.children, targetId);
  654. if (foundNode) {
  655. return foundNode;
  656. }
  657. }
  658. }
  659. return null;
  660. },
  661. /** 转换数据为树形结构 */
  662. transformToTree(records) {
  663. const recordMap = {}; // 创建一个 Map 以存储所有记录
  664. const tree = []; // 最终返回的树形结构
  665. // 初始化所有记录到 Map
  666. records.forEach((record) => {
  667. recordMap[record.workareaId] = {
  668. id: record.workareaId,
  669. label: record.workareaName,
  670. map: record.map,
  671. mapImg: record.mapImg,
  672. children: [],
  673. };
  674. });
  675. // 遍历记录并构建树
  676. records.forEach((record) => {
  677. const parentId = record.parentId;
  678. if (parentId === "0") {
  679. // 如果是顶层节点,直接添加到树中
  680. tree.push(recordMap[record.workareaId]);
  681. } else if (recordMap[parentId]) {
  682. // 如果有父节点,则将当前节点加入父节点的 children 中
  683. recordMap[parentId].children.push(recordMap[record.workareaId]);
  684. }
  685. });
  686. return tree;
  687. },
  688. // 树节点筛选逻辑
  689. filterNode(value, data) {
  690. if (!value) return true; // 如果没有输入值,显示所有节点
  691. return data.label.indexOf(value) !== -1; // 判断节点 label 是否包含输入值
  692. },
  693. // 监听输入框变化
  694. handleInputChange() {
  695. this.$refs.tree.filter(this.workareaName); // 调用树的 filter 方法
  696. },
  697. // 节点单击事件
  698. handleNodeClick(data) {
  699. console.log(data, "单节点点击");
  700. this.treeSelectMap = data;
  701. if (
  702. this.$route.query.sopId === "null" ||
  703. this.$route.query.ticketId === "null"
  704. ) {
  705. // this.setMapData(data.map);
  706. console.log("设置了地图数据");
  707. }
  708. // 传递车间地图
  709. this.imgsrc = data.mapImg;
  710. this.workareaName = data.label;
  711. this.handleInputChange();
  712. },
  713. // 详情数据
  714. getSopInfo() {
  715. const sopId = this.$route.query.sopId;
  716. console.log(this.$route.query.sopId, "接受路由参数");
  717. if (sopId !== null) {
  718. selectIsSopById(sopId).then((response) => {
  719. console.log(response, "详细内容");
  720. this.orderTableData=response.data.pointDetailVOList.map((point)=>{
  721. return{
  722. pointName: point.pointName, // 显示的名称
  723. pointId: point.pointId, // 对应的值
  724. pointType: point.pointType,
  725. powerType: point.powerType,
  726. prePointId: point.prePointId
  727. }
  728. })
  729. this.sopProps = [response.data];
  730. this.title = "修改隔离点信息";
  731. this.form = response.data;
  732. this.workareaName = response.data.workareaId;
  733. if (response.data.ticketUserDTOList.length > 0) {
  734. this.openStaffing = true;
  735. }
  736. const value =response.data.ticketUserDTOList? response.data.ticketUserDTOList //找到上锁人 这里一定要先筛选locker再去给表格筛选 否则表格筛选之后直接不会有上锁人数据了
  737. .filter((item) => item.userRole == "jtlocker")
  738. .map((item) => item.userName):[];
  739. if(value){
  740. this.form.locker = value[0] //map返回的是数字 所以这样写
  741. }
  742. this.form.ticketUserDTOList =response.data.ticketUserDTOList? response.data.ticketUserDTOList.filter(
  743. (item) => {
  744. return item.userRole !== "jtlocker";
  745. }
  746. ):[]; //过滤上锁人
  747. });
  748. } else {
  749. this.title = "新增隔离点信息";
  750. this.setSopEdit(true);
  751. this.setSelectSopPoints([]);
  752. this.setPointTableData([]);
  753. this.tableData = null;
  754. this.form = {
  755. spoint: [],
  756. sopContent: "",
  757. sopCode: "",
  758. sopName: "",
  759. sopType: "",
  760. workareaId: "",
  761. workshopId: "",
  762. };
  763. this.autoGenFlag = false;
  764. }
  765. },
  766. submit() {
  767. console.log("我点击了确认");
  768. // 确保 this.form.spoint 是一个数组,如果为空则默认空数组
  769. if (!Array.isArray(this.form.spoint)) {
  770. this.form.spoint = [];
  771. }
  772. // 如果没有选中点,逆向传递为空时,使用当前表格数据中的点
  773. if (this.form.spoint.length === 0 && Array.isArray(this.tableData)) {
  774. this.form.spoint = this.tableData.map((point) => point.pointId);
  775. }
  776. // 编辑模式
  777. if (this.$route.query.sopId !== "null") {
  778. console.log(this.$route.query.sopId, "sopIdaaa");
  779. // 确保 sopId 存在
  780. if (!this.form.sopId) {
  781. console.error("隔离点id不可为空!");
  782. this.$message.error("隔离点id不可为空!"); // 使用消息提示
  783. return;
  784. }
  785. const selectedpointIds = this.form.spoint.join(",");
  786. const UserList = [
  787. ...this.form.ticketUserDTOList,
  788. ...this.newticketUserDTOList,
  789. ];
  790. const pointsList = this.form.pointDetailVOList.map((item) => {
  791. return {
  792. pointId: item.pointId,
  793. prePointId: item.prePointId,
  794. };
  795. });
  796. console.log(this.form.pointsList);
  797. const data = {
  798. pointIds: selectedpointIds,
  799. sopContent: this.form.sopContent,
  800. sopCode: this.form.sopCode,
  801. sopName: this.form.sopName,
  802. sopType: this.form.sopType,
  803. workareaId: this.emitworklineId,
  804. ticketUserDTOList: UserList,
  805. pointsList: pointsList,
  806. // workshopId: this.emitWorkShop.value
  807. };
  808. data.sopId = this.form.sopId;
  809. console.log(data, "编辑的参数");
  810. updateIsSop(data).then((res) => {
  811. console.log(res, "修改接口");
  812. if (res.code == 200) {
  813. this.$router.push("/sop/sopm");
  814. this.$message.success("SOP修改成功");
  815. }
  816. });
  817. } else {
  818. // 新增模式
  819. const selectedpointIds = this.form.spoint.join(",");
  820. const UserList = [
  821. ...this.form.ticketUserDTOList,
  822. ...this.newticketUserDTOList,
  823. ];
  824. const pointsList = this.tableData.map((item) => {
  825. return {
  826. pointId: item.pointId,
  827. prePointId: item.prePointId,
  828. };
  829. });
  830. console.log(this.form.pointsList);
  831. const data = {
  832. pointIds: selectedpointIds,
  833. sopContent: this.form.sopContent,
  834. sopCode: this.form.sopCode,
  835. sopName: this.form.sopName,
  836. sopType: this.form.sopType,
  837. workareaId: this.emitworklineId,
  838. ticketUserDTOList: UserList,
  839. pointsList: pointsList,
  840. // workshopId: this.emitWorkShop.value
  841. };
  842. console.log(data, "新增参数");
  843. addinsertIsSop(data).then((res) => {
  844. console.log(res, "新增接口");
  845. if (res.code == 200) {
  846. this.$router.push("/sop/sopm");
  847. this.$message.success("SOP新建成功");
  848. }
  849. });
  850. }
  851. },
  852. // 选中隔离点 前置节点的change函数
  853. onDropdownVisibleChange(row) {
  854. console.log(row, "我执行这里拉");
  855. // 当前节点 ID
  856. const currentPointId = row.pointId;
  857. // 获取当前行的 prePointId
  858. const currentPrePointId = row.prePointId;
  859. // 已经被选为前置节点的 ID 集合
  860. const selectedPrePointIds = new Set(
  861. this.tableData
  862. .filter((item) => item.prePointId !== null)
  863. .map((item) => item.prePointId)
  864. );
  865. // console.log(selectedPrePointIds, 'selectedPrePointIds')
  866. // 构建 form.prePointId 数组对象
  867. this.form.prePointId = this.tableData.map((item) => ({
  868. pointId: item.pointId,
  869. prePointId: item.prePointId || null,
  870. }));
  871. // 每次都从原始数据开始过滤
  872. let filteredOptions = [...this.initprePointIdOptions];
  873. // 过滤规则:
  874. // 1. 排除自身
  875. // 2. 排除已经被选为前置节点的隔离点
  876. // 3. 排除所有已经选为前置节点的节点及其前置节点
  877. const allExcludedPoints = new Set([currentPointId]);
  878. this.getAllExcludedPoints(currentPointId, allExcludedPoints);
  879. filteredOptions = filteredOptions.filter((option) => {
  880. return !allExcludedPoints.has(option.pointId);
  881. });
  882. this.prePointIdOptions = filteredOptions;
  883. console.log("过滤后的前置节点选项", this.prePointIdOptions);
  884. },
  885. // 递归获取所有需要排除的节点
  886. getAllExcludedPoints(pointId, excludedPoints) {
  887. const relatedRows = this.tableData.filter(
  888. (item) => item.prePointId === pointId
  889. );
  890. for (const row of relatedRows) {
  891. excludedPoints.add(row.pointId);
  892. this.getAllExcludedPoints(row.pointId, excludedPoints);
  893. }
  894. },
  895. // 前置节点改变时的处理函数
  896. prePointIdChange(row) {
  897. console.log(row, "前置节点改变");
  898. // 更新 tableData 中对应行的 prePointId
  899. const index = this.tableData.findIndex(
  900. (item) => item.pointId === row.pointId
  901. );
  902. if (index !== -1) {
  903. this.$set(this.tableData, index, row);
  904. }
  905. // 重新调用 onDropdownVisibleChange 确保其他节点的选项更新
  906. this.onDropdownVisibleChange(row);
  907. },
  908. // 定义一个排序函数,根据 orderTableData 中 pointName 的顺序对 tableData 进行排序
  909. sortTableDataByOrder(tableData, orderTableData) {
  910. // 构建 orderMap,使用 pointName 作为键,索引作为值
  911. const orderMap = new Map(orderTableData.map((item, index) => [item.pointName, index]))
  912. return tableData.sort((a, b) => {
  913. // 如果 pointName 在 orderMap 中,按 orderMap 的索引排序
  914. // 如果 pointName 不在 orderMap 中,排在最后,并按 pointName 的自然顺序排列
  915. const indexA = orderMap.has(a.pointName) ? orderMap.get(a.pointName) : Infinity
  916. const indexB = orderMap.has(b.pointName) ? orderMap.get(b.pointName) : Infinity
  917. if (indexA === indexB) {
  918. // 当两者都不在 orderMap 中时,按 pointName 的自然顺序排列
  919. return a.pointName.localeCompare(b.pointName)
  920. }
  921. return indexA - indexB
  922. })
  923. },
  924. // 子组件选中的隔离点逆传递拿到的数据
  925. handleSelectPoint(points) {
  926. console.log(points, "父组件接收逆向传递选中的隔离点");
  927. // 1. 去除重复的点,使用 Set 确保每个 pointId 唯一
  928. const uniquePoints = Array.from(
  929. new Set(points.map((point) => point.pointId))
  930. ).map((id) => points.find((point) => point.pointId === id));
  931. console.log(uniquePoints, "去重后的选中节点");
  932. this.tableData = this.sortTableDataByOrder(uniquePoints, this.orderTableData);//去重并排序
  933. // this.tableData = uniquePoints; // 子组件传递过来的选中节点(去重后)
  934. // 使用 Set 来存储传递过来的点值
  935. const newValues = new Set(uniquePoints.map((point) => point.pointId));
  936. // 2. 删除取消选中的点
  937. const removedPoints = this.tableData
  938. .filter((item) => !newValues.has(item.pointId))
  939. .map((item) => item.pointId); // 记录被删除的点
  940. this.tableData = this.tableData.filter((item) =>
  941. newValues.has(item.pointId)
  942. );
  943. // 3. 确保新增点不会重复
  944. const existingValues = new Set(
  945. this.tableData.map((item) => item.pointId)
  946. );
  947. uniquePoints.forEach((point) => {
  948. // 如果当前传递的点不在已有的点集中,则添加
  949. if (!existingValues.has(point.pointId)) {
  950. this.tableData.push({
  951. pointName: point.pointName, // 显示的名称
  952. pointId: point.pointId, // 对应的值
  953. pointType: point.pointType,
  954. powerType: point.powerType,
  955. prePointId: null,
  956. });
  957. this.prePointIdOptions.push({
  958. pointName: point.pointName, // 显示的名称
  959. pointId: point.pointId, // 对应的值
  960. });
  961. this.initprePointIdOptions = [...this.prePointIdOptions];
  962. console.log(this.prePointIdOptions, "前置节点设置下拉");
  963. existingValues.add(point.pointId);
  964. }
  965. });
  966. // 4. 处理被删除的点,如果这些点作为父节点绑定,则将对应的 prePointId 设置为 null
  967. this.tableData.forEach((item) => {
  968. if (removedPoints.includes(item.prePointId)) {
  969. item.prePointId = null;
  970. }
  971. });
  972. // 5. 从下拉选项中移除被删除的点
  973. this.prePointIdOptions = this.prePointIdOptions.filter(
  974. (option) => !removedPoints.includes(option.pointId)
  975. );
  976. this.initprePointIdOptions = [...this.prePointIdOptions];
  977. // 6. 确保下拉选项中仍然保留所有未被删除的点
  978. const allPoints = uniquePoints.map((point) => ({
  979. pointName: point.pointName,
  980. pointId: point.pointId,
  981. }));
  982. this.prePointIdOptions = allPoints.filter(
  983. (option) => !removedPoints.includes(option.pointId)
  984. );
  985. this.initprePointIdOptions = [...this.prePointIdOptions];
  986. // 更新 form.spoint 为最新选中的隔离点数组
  987. this.form.spoint = uniquePoints.map((point) => point.pointId);
  988. },
  989. // handleSelectPoint(points) {
  990. // console.log(points, '父组件接收逆向传递选中的隔离点')
  991. // this.tableData = points; //子组件传递过来的选中节点
  992. // // 使用 Set 来存储传递过来的点值
  993. // const newValues = new Set(points.map((point) => point.pointId))
  994. //
  995. // // 1. 删除取消选中的点
  996. // const removedPoints = this.tableData
  997. // .filter((item) => !newValues.has(item.pointId))
  998. // .map((item) => item.pointId) // 记录被删除的点
  999. //
  1000. // this.tableData = this.tableData.filter((item) =>
  1001. // newValues.has(item.pointId)
  1002. // )
  1003. // // 2. 确保新增点不会重复
  1004. // const existingValues = new Set(
  1005. // this.tableData.map((item) => item.pointId)
  1006. // )
  1007. //
  1008. // points.forEach((point) => {
  1009. // // 如果当前传递的点不在已有的点集中,则添加
  1010. // if (!existingValues.has(point.pointId)) {
  1011. // this.tableData.push({
  1012. // pointName: point.pointName, // 显示的名称
  1013. // pointId: point.pointId, // 对应的值
  1014. // pointType: point.pointType,
  1015. // powerType: point.powerType,
  1016. // prePointId: null
  1017. // })
  1018. //
  1019. // this.prePointIdOptions.push({
  1020. // pointName: point.pointName, // 显示的名称
  1021. // pointId: point.pointId // 对应的值
  1022. // })
  1023. // this.initprePointIdOptions = [...this.prePointIdOptions]
  1024. // console.log(this.prePointIdOptions, '前置节点设置下拉')
  1025. // existingValues.add(point.pointId)
  1026. // }
  1027. // })
  1028. //
  1029. // // 3. 处理被删除的点,如果这些点作为父节点绑定,则将对应的 prePointId 设置为 null
  1030. // this.tableData.forEach((item) => {
  1031. // if (removedPoints.includes(item.prePointId)) {
  1032. // item.prePointId = null
  1033. // }
  1034. // })
  1035. //
  1036. // // 4. 从下拉选项中移除被删除的点
  1037. // this.prePointIdOptions = this.prePointIdOptions.filter(
  1038. // (option) => !removedPoints.includes(option.pointId)
  1039. // )
  1040. // this.initprePointIdOptions = [...this.prePointIdOptions]
  1041. //
  1042. // // 5. 确保下拉选项中仍然保留所有未被删除的点
  1043. // const allPoints = points.map((point) => ({
  1044. // pointName: point.pointName,
  1045. // pointId: point.pointId
  1046. // }))
  1047. //
  1048. // this.prePointIdOptions = allPoints.filter(
  1049. // (option) => !removedPoints.includes(option.pointId)
  1050. // )
  1051. // this.initprePointIdOptions = [...this.prePointIdOptions]
  1052. //
  1053. // // 更新 form.spoint 为最新选中的隔离点数组
  1054. // this.form.spoint = points.map((point) => point.pointId)
  1055. //
  1056. // },
  1057. // 车间逆向传递拿到的隔离点数据产线
  1058. handleProductLineSelected(selectedOption) {
  1059. // console.log(selectedOption, "父组件接收到的 selectedOption");
  1060. this.points = selectedOption;
  1061. this.form.workline = selectedOption.label;
  1062. // console.log(this.worklineMap.length, '父组件接收到的 worklineMap')
  1063. },
  1064. // 车间子组件逆传递车间相关数据车间
  1065. handleWorkshopSelected(selectedOption) {
  1066. console.log(selectedOption, "handleWorkshopSelected");
  1067. // this.emitWorkShop = selectedOption
  1068. // this.form.workshopName = selectedOption.label;//这里是回显车间的 暂时不需要
  1069. this.form.workline = selectedOption.label; //这里是回显作业区域的
  1070. this.emitworklineId = selectedOption.id;
  1071. this.worklineMap = selectedOption.map;
  1072. },
  1073. // 添加内部人员
  1074. addInside() {
  1075. this.open = true;
  1076. this.title = "添加内部人员";
  1077. this.insideMumber = true;
  1078. this.outsideMumber = false;
  1079. // this.form.ticketUserDTOList = [];
  1080. this.dialogForm.nickName = "";
  1081. },
  1082. addOutside() {
  1083. this.open = true;
  1084. this.title = "添加外部人员";
  1085. this.insideMumber = false;
  1086. this.outsideMumber = true;
  1087. this.dialogForm.username = null;
  1088. },
  1089. // 取消按钮
  1090. cancel() {
  1091. this.open = false;
  1092. },
  1093. // 人员列表删除
  1094. deleteRow(index, rows) {
  1095. console.log(index, rows, "删除的行");
  1096. const deletedItem = rows[index]; // 获取要删除的项
  1097. rows.splice(index, 1); // 从显示的列表中删除
  1098. const formIndex = this.form.ticketUserDTOList.findIndex(
  1099. (item) => item.userId === deletedItem.userId
  1100. );
  1101. if (formIndex !== -1) {
  1102. this.form.ticketUserDTOList.splice(formIndex, 1); // 从 form.ticketUserDTOList 中删除
  1103. }
  1104. },
  1105. // 上锁人下拉选择change事件
  1106. handlelockerChage(val) {
  1107. console.log(val, "上锁人chage");
  1108. const user = this.listLockerOption.find((item) => item.value === val);
  1109. if (user && this.form.locker !== "") {
  1110. const existingUser = this.form.ticketUserDTOList.find(
  1111. (u) => u.userName === user.label
  1112. );
  1113. if (!existingUser) {
  1114. this.newticketUserDTOList.push({
  1115. userName: user.label,
  1116. userId: user.value,
  1117. userType: 0,
  1118. userRole: "jtlocker",
  1119. });
  1120. console.log(this.newticketUserDTOList, "用户");
  1121. } else {
  1122. // console.log('用户已存在', user.label)
  1123. }
  1124. }
  1125. },
  1126. // 添加内部人员的用户新增到ticketUserDTOList这个数据里
  1127. changeInsideUser(values) {
  1128. const usersinside = values
  1129. .map((value) =>
  1130. this.listCoLockerOption.find((item) => item.value === value)
  1131. )
  1132. .filter(Boolean);
  1133. usersinside.forEach((user) => {
  1134. const existingUser = this.form.ticketUserDTOList.find(
  1135. (u) => u.userName === user.label
  1136. );
  1137. // console.log(usersinside, 'usersinside----67')
  1138. if (!existingUser) {
  1139. this.form.ticketUserDTOList.push({
  1140. userName: user.label,
  1141. userId: user.value,
  1142. userType: 0,
  1143. userRole: "jtcolocker",
  1144. });
  1145. console.log(this.form.ticketUserDTOList, "用户");
  1146. } else {
  1147. // console.log('用户已存在', user.label)
  1148. }
  1149. });
  1150. this.updateCoLocker();
  1151. // console.log(this.form.ticketUserDTOList, '用户')
  1152. },
  1153. // 添加外部人员 输入名称 userType==1是共锁人 0是上锁人 userId==0
  1154. outSideUserInput(event) {
  1155. this.dialogForm.username = event;
  1156. },
  1157. // 添加外部人员弹窗 添加给表格数据的按钮事件
  1158. insertOutSideTable() {
  1159. this.OutSideUserTableData.push({
  1160. userName: this.dialogForm.username,
  1161. userId: this.nextUserId++,
  1162. });
  1163. this.dialogForm.username = "";
  1164. console.log(this.OutSideUserTableData, "OutSideUserTableData");
  1165. },
  1166. // 添加外部人员 确认弹窗
  1167. outSideDialogConfirm() {
  1168. this.updateCoLocker();
  1169. this.open = false;
  1170. },
  1171. // 更新界面中共锁人下拉框显示的内容
  1172. updateCoLocker() {
  1173. // 检查并补充 ticketUserDTOList 中缺少的用户
  1174. this.OutSideUserTableData.forEach((item) => {
  1175. const existingUser = this.form.ticketUserDTOList.find(
  1176. (u) => u.userName === item.userName
  1177. );
  1178. if (!existingUser) {
  1179. this.form.ticketUserDTOList.push({
  1180. userName: item.userName,
  1181. userId: 0,
  1182. userType: 1,
  1183. userRole: "jtcolocker",
  1184. });
  1185. }
  1186. });
  1187. console.log(this.form.ticketUserDTOList, "最终的 ticketUserDTOList");
  1188. },
  1189. //自动生成编码
  1190. handleAutoGenChange(autoGenFlag) {
  1191. if (autoGenFlag) {
  1192. genCode("SOP_CODE").then((response) => {
  1193. this.form.sopCode = response;
  1194. });
  1195. } else {
  1196. this.form.sopCode = null;
  1197. }
  1198. },
  1199. //是否开启人员配置界面
  1200. handleOpenStaffing(openStaffing) {
  1201. // 定义一个函数来封装接口调用逻辑
  1202. const fetchUserData = (roleKey) => {
  1203. const data = {
  1204. pageNum: 1,
  1205. pageSize: 10000,
  1206. roleKey: roleKey,
  1207. };
  1208. return SopUser(data)
  1209. .then((res) => {
  1210. // console.log(res, `上锁人 - ${roleKey}`);
  1211. return res; // 返回结果以便后续处理
  1212. })
  1213. .catch((err) => {
  1214. // console.error(err, `请求失败 - ${roleKey}`);
  1215. throw err; // 抛出错误以便捕获
  1216. });
  1217. };
  1218. // 调用两次接口,分别传递不同的 roleKey
  1219. Promise.all([fetchUserData("jtlocker"), fetchUserData("jtcolocker")])
  1220. .then((results) => {
  1221. // 处理两次调用的结果
  1222. const [jtlockerResult, jtcolockerResult] = results;
  1223. console.log(jtlockerResult, jtcolockerResult, "jtlocker 结果");
  1224. this.listLockerOption = jtlockerResult.rows.map((item) => {
  1225. return {
  1226. label: item.nickName,
  1227. value: item.userId,
  1228. };
  1229. });
  1230. this.listCoLockerOption = jtcolockerResult.rows.map((item) => {
  1231. return {
  1232. label: item.nickName,
  1233. value: item.userId,
  1234. };
  1235. });
  1236. })
  1237. .catch((err) => {
  1238. console.error(err, "其中一个请求失败");
  1239. });
  1240. if (openStaffing) {
  1241. console.log(openStaffing, "开启人员配置");
  1242. this.openStaffing = openStaffing;
  1243. } else {
  1244. console.log(openStaffing, "关闭人员配置");
  1245. this.openStaffing = openStaffing;
  1246. // this.activeName = "first";
  1247. }
  1248. },
  1249. // 侧边X关闭
  1250. goBack() {
  1251. this.$router.push("/sop/sopm");
  1252. },
  1253. // methods结束
  1254. },
  1255. };
  1256. </script>
  1257. <style scoped lang="scss">
  1258. .newOperations {
  1259. width: 99%;
  1260. height: 100%;
  1261. // background: pink;
  1262. margin: 10px;
  1263. display: flex;
  1264. position: relative;
  1265. .left {
  1266. width: 75%;
  1267. height: 830px;
  1268. // background: #eee;
  1269. margin-right: 10px;
  1270. }
  1271. .lefttree {
  1272. width: 18%;
  1273. height: 100%;
  1274. position: absolute;
  1275. left: 0;
  1276. top: 2%;
  1277. display: flex;
  1278. // background: pink;
  1279. .lefttree-card {
  1280. height: 98%;
  1281. .title {
  1282. display: block;
  1283. width: 30%;
  1284. height: 30px;
  1285. text-align: center;
  1286. margin: 0 0 5%;
  1287. border-bottom: 2px solid #1684fc;
  1288. color: rgb(22, 132, 252);
  1289. }
  1290. }
  1291. .item {
  1292. width: 30px;
  1293. height: 30px;
  1294. font-size: 20px;
  1295. display: flex;
  1296. justify-content: center;
  1297. align-items: center;
  1298. // .btnwork {
  1299. // width: 100%;
  1300. // height: 100%;
  1301. // display: flex; /* 使用 flex 布局 */
  1302. // justify-content: center; /* 水平居中 */
  1303. // align-items: center; /* 垂直居中 */
  1304. // font-size: 20px;
  1305. // box-sizing: border-box;
  1306. // }
  1307. }
  1308. }
  1309. .right {
  1310. flex: 1;
  1311. height: 100%;
  1312. // background: #000;
  1313. .right_top {
  1314. height: 840px;
  1315. // background: pink;
  1316. .box-card {
  1317. height: 100%;
  1318. overflow-y: auto;
  1319. .clearfix {
  1320. width: 100%;
  1321. position: absolute;
  1322. top: 0;
  1323. // line-height: 40px;
  1324. padding: 12px 0 0;
  1325. box-sizing: border-box;
  1326. background: #fff;
  1327. z-index: 10;
  1328. }
  1329. }
  1330. .box-card::-webkit-scrollbar {
  1331. display: none;
  1332. }
  1333. }
  1334. .title {
  1335. display: block;
  1336. width: 20%;
  1337. height: 30px;
  1338. text-align: center;
  1339. margin: 0 0 5%;
  1340. border-bottom: 2px solid #1684fc;
  1341. color: rgb(22, 132, 252);
  1342. }
  1343. }
  1344. }
  1345. .newOperations::-webkit-scrollbar {
  1346. display: none;
  1347. }
  1348. //右侧卡片样式开始
  1349. .text {
  1350. font-size: 14px;
  1351. }
  1352. .item {
  1353. margin-bottom: 18px;
  1354. p {
  1355. font-size: 18px;
  1356. font-weight: bolder;
  1357. font-family: SourceHanSansSC-bold;
  1358. }
  1359. }
  1360. // ::v-deep .el-card__header {
  1361. // position: fixed;
  1362. // top: 60px;
  1363. // z-index: 10000000;
  1364. // background: pink;
  1365. // }
  1366. .clearfix:before,
  1367. .clearfix:after {
  1368. display: table;
  1369. content: "";
  1370. width: 320px;
  1371. }
  1372. .clearfix:after {
  1373. clear: both;
  1374. }
  1375. .box-card {
  1376. // width: 390px;
  1377. width: 100%;
  1378. height: 850px;
  1379. //background: pink;
  1380. }
  1381. ::v-deeep .el-tabs--top .el-tabs__item.is-top:nth-child(2),
  1382. .el-tabs--top .el-tabs__item.is-bottom:nth-child(2),
  1383. .el-tabs--bottom .el-tabs__item.is-top:nth-child(2),
  1384. .el-tabs--bottom .el-tabs__item.is-bottom:nth-child(2) {
  1385. padding-left: 100px !important;
  1386. }
  1387. ::v-deep .el-tabs .el-tabs__item {
  1388. padding: 0 30px !important;
  1389. }
  1390. .loadbox {
  1391. width: 100%;
  1392. height: 100%;
  1393. background: rgba($color: #fff, $alpha: 0.9);
  1394. position: absolute;
  1395. left: 0;
  1396. top: 0;
  1397. z-index: 200;
  1398. padding: 18% 45%;
  1399. box-sizing: border-box;
  1400. h5 {
  1401. font-size: 30px;
  1402. }
  1403. .el-icon-loading {
  1404. font-size: 50px;
  1405. margin-left: 12%;
  1406. }
  1407. }
  1408. //右侧卡片样式结束
  1409. </style>