scenePacketList.vue 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222
  1. <template>
  2. <div class="scenePacketListPanel">
  3. <div class="viewBox">
  4. <el-button icon="el-icon-view" @click="viewTree" type="primary"
  5. >预览</el-button
  6. >
  7. </div>
  8. <tableList ref="table" :columns="columns" :getDataWay="getDataWay">
  9. <el-table-column label="操作" slot="cgInfos" align="center" type="">
  10. <template v-slot="scope">
  11. <i
  12. v-if="
  13. (scope.row.children &&
  14. scope.row.children.length > 0) ||
  15. (!scope.row.children && scope.row.sceneNum === 0) ||
  16. (scope.row.children &&
  17. scope.row.children.length === 0 &&
  18. scope.row.sceneNum === 0)
  19. "
  20. @click="addIndicators(scope.row)"
  21. class="el-icon-plus elIcon"
  22. title="添加"
  23. ></i>
  24. <i
  25. @click="editRow(scope.row)"
  26. class="el-icon-edit-outline elIcon"
  27. title="编辑"
  28. ></i>
  29. <i
  30. v-if="scope.row.parentId != '0'"
  31. @click="delRow(scope.row)"
  32. class="el-icon-delete elIcon"
  33. title="删除"
  34. ></i>
  35. <i
  36. v-if="
  37. scope.row.parentId != '0' &&
  38. (!scope.row.children ||
  39. scope.row.children.length === 0)
  40. "
  41. @click="addScenario(scope.row)"
  42. class="el-icon-document-add elIcon"
  43. title="添加场景"
  44. ></i>
  45. </template>
  46. </el-table-column>
  47. <el-table-column label="指标名称" slot="sublistName" align="left">
  48. <template v-slot="scope">
  49. <span>{{ scope.row.sublistName }}</span>
  50. </template>
  51. </el-table-column>
  52. <el-table-column label="权重%" slot="weight" align="center">
  53. <template v-slot="scope">
  54. <span v-if="scope.row.weightErr" style="color: red">{{
  55. scope.row.weight
  56. }}</span>
  57. <span v-else>{{ scope.row.weight }}</span>
  58. </template>
  59. </el-table-column>
  60. </tableList>
  61. <div class="btns">
  62. <el-button
  63. type="primary"
  64. v-if="
  65. share === '0' ||
  66. share === '' ||
  67. ((roleCode === '0' || roleCode === '1') && share === '1')
  68. "
  69. @click="save(false)"
  70. >保存</el-button
  71. >
  72. <el-button
  73. type="primary"
  74. v-if="share === '0' || share === '1'"
  75. @click="save(true)"
  76. >另存为</el-button
  77. >
  78. <el-button type="primary" plain @click="cancel">取消</el-button>
  79. </div>
  80. <el-dialog
  81. :title="nameDiaTitle"
  82. :visible.sync="indicatorsVisible"
  83. width="690px"
  84. :close-on-click-modal="false"
  85. :close-on-press-escape="false"
  86. :before-close="indicatorsCancel"
  87. >
  88. <el-form
  89. ref="form"
  90. :model="form"
  91. :rules="rules"
  92. label-width="108px"
  93. >
  94. <el-form-item label="指标名称:" prop="sublistName">
  95. <el-input
  96. placeholder="请输入"
  97. maxlength="20"
  98. v-autoTrim="{ obj: form, key: 'sublistName' }"
  99. v-model="form.sublistName"
  100. >
  101. </el-input>
  102. </el-form-item>
  103. <el-form-item label="权重%:" prop="weight">
  104. <el-input
  105. placeholder="请输入"
  106. maxlength="6"
  107. v-autoTrim="{ obj: form, key: 'weight' }"
  108. v-model="form.weight"
  109. :disabled="editType === 'edit' && isRoot"
  110. >
  111. </el-input>
  112. </el-form-item>
  113. <el-form-item label="备注:" prop="remarks">
  114. <el-input
  115. v-autoTrim="{
  116. obj: form,
  117. key: 'remarks',
  118. }"
  119. v-model="form.remarks"
  120. type="textarea"
  121. placeholder="请输入"
  122. :autosize="{ minRows: 4, maxRows: 4 }"
  123. maxlength="300"
  124. ></el-input>
  125. </el-form-item>
  126. </el-form>
  127. <span slot="footer">
  128. <el-button type="primary" @click="indicatorsConfirm"
  129. >确 定</el-button
  130. >
  131. <el-button @click="indicatorsCancel">取 消</el-button>
  132. </span>
  133. </el-dialog>
  134. <el-dialog
  135. title="场景分类"
  136. :visible.sync="scenarioVisible"
  137. width="690px"
  138. :close-on-click-modal="false"
  139. :close-on-press-escape="false"
  140. :before-close="scenarioCancel"
  141. >
  142. <el-form
  143. ref="formA"
  144. :model="formA"
  145. :rules="rulesA"
  146. label-width="108px"
  147. >
  148. <el-form-item label="场景分类:" prop="sceneType">
  149. <el-select v-model="formA.sceneType">
  150. <el-option
  151. v-for="item in sceneTypeList"
  152. :label="item.caption"
  153. :value="item.code"
  154. :key="item.code"
  155. ></el-option>
  156. </el-select>
  157. </el-form-item>
  158. <el-form-item label="评分规则:" prop="ruleNameArrayS">
  159. <el-cascader
  160. ref="cascader"
  161. v-model="formA.ruleNameArrayS"
  162. :options="ruleList"
  163. :props="props"
  164. @change="ruleSelChange"
  165. ></el-cascader>
  166. <!-- <el-select v-model="formA.rulesId" @change="ruleSelChange">
  167. <el-option
  168. v-for="item in ruleList"
  169. :label="item.ruleName"
  170. :value="item.rulesId"
  171. :key="item.rulesId"
  172. ></el-option>
  173. </el-select> -->
  174. </el-form-item>
  175. </el-form>
  176. <div class="tips">
  177. 解释:基于不同环境要素,在前述主题场景及两条路径的框架下进行场景的精确细分。细分维度包括天气、季节、温度、路况、车况等多种元素,所采纳元素的广度和深度既与需求有关,也与汽车智能化程度(感知能力)相关
  178. </div>
  179. <span slot="footer">
  180. <el-button type="primary" @click="scenarioConfirm"
  181. >下一步</el-button
  182. >
  183. <el-button @click="scenarioCancel">取 消</el-button>
  184. </span>
  185. </el-dialog>
  186. <el-dialog
  187. title="真实场景"
  188. :visible.sync="scenarioListsVisible"
  189. width="90%"
  190. class="scenarioListsDia"
  191. :close-on-click-modal="false"
  192. :close-on-press-escape="false"
  193. :before-close="scenarioListsCancel"
  194. >
  195. <real-scene-list ref="realScene"></real-scene-list>
  196. <span slot="footer">
  197. <el-button type="primary" @click="scenarioListsConfirm"
  198. >确 定</el-button
  199. >
  200. <el-button @click="scenarioListsCancel">取 消</el-button>
  201. </span>
  202. </el-dialog>
  203. <el-dialog
  204. v-if="generalizationVisible"
  205. :visible.sync="generalizationVisible"
  206. :title="generalizationDiaTitle"
  207. width="90%"
  208. class="generalizationDia"
  209. :close-on-click-modal="false"
  210. :close-on-press-escape="false"
  211. :before-close="generalizationCancel"
  212. >
  213. <el-steps :active="stepActive" align-center>
  214. <el-step title="第一步" description="选择场景模板"></el-step>
  215. <el-step title="第二步" description="场景泛化"></el-step>
  216. </el-steps>
  217. <div class="changeBtn">
  218. <el-button
  219. type="primary"
  220. v-if="stepActive === 2"
  221. @click="changeTemplate"
  222. >更换模板</el-button
  223. >
  224. </div>
  225. <div>
  226. <generalization-list
  227. v-if="stepActive === 1"
  228. ref="generalizationList"
  229. ></generalization-list>
  230. <generalization-detail
  231. v-if="stepActive === 2"
  232. ref="generalizationDetail"
  233. :id="generalizationId"
  234. :curId="curNode.id"
  235. :exampleId="curNode.exampleId"
  236. :ruleName="formA.ruleName"
  237. :rulesId="formA.rulesId"
  238. :ruleNameArrayS="formA.ruleNameArrayS"
  239. :genUrlType="genUrlType"
  240. @generalizationBegin="generalizationBegin"
  241. @generalizationDone="generalizationDone"
  242. ></generalization-detail>
  243. </div>
  244. <span slot="footer">
  245. <!-- <el-button
  246. v-if="stepActive === 2"
  247. type="primary"
  248. @click="generalizationPrev"
  249. >上一步</el-button
  250. > -->
  251. <el-button
  252. v-if="stepActive === 1"
  253. type="primary"
  254. @click="generalizationNext"
  255. >下一步</el-button
  256. >
  257. <el-button
  258. v-if="stepActive === 2"
  259. type="primary"
  260. @click="generalizationConfirm"
  261. >完成</el-button
  262. >
  263. <!-- <el-button @click="generalizationCancel">取 消</el-button> -->
  264. </span>
  265. </el-dialog>
  266. <el-dialog
  267. title="模板预览"
  268. v-if="templateViewVisible"
  269. :visible.sync="templateViewVisible"
  270. width="90%"
  271. class="templateViewDia"
  272. :close-on-click-modal="false"
  273. :close-on-press-escape="false"
  274. :before-close="templateViewClose"
  275. >
  276. <!-- <view-tree :data="treeData"></view-tree> -->
  277. <template-view
  278. :viewData="treeData"
  279. :errArr="weightErrIds"
  280. ></template-view>
  281. <span slot="footer">
  282. <el-button type="primary" @click="templateViewClose"
  283. >关 闭</el-button
  284. >
  285. </span>
  286. </el-dialog>
  287. </div>
  288. </template>
  289. <script>
  290. import searchLayout from "@/components/grid/searchLayout";
  291. import tableList from "@/components/grid/TableList";
  292. import toolbarTab from "@/components/toolbar/toolbarTab";
  293. import realSceneList from "./components/realSceneList";
  294. import generalizationList from "./components/generalizationList";
  295. import generalizationDetail from "./components/generalizationDetail";
  296. // import viewTree from "./components/elTree";
  297. import templateView from "./components/templateView";
  298. import { mapState } from "vuex";
  299. export default {
  300. name: "scenePacketList", // 场景测试包
  301. components: {
  302. searchLayout,
  303. tableList,
  304. toolbarTab,
  305. realSceneList,
  306. generalizationList,
  307. generalizationDetail,
  308. // viewTree,
  309. templateView,
  310. },
  311. data() {
  312. let validateNum = (rule, value, callback) => {
  313. // 修改一级指标时,权重值为number类型,其余为string
  314. if (typeof value === "number") {
  315. value = value + "";
  316. }
  317. if (value == 0 || value > 100) {
  318. callback(new Error(rule.message));
  319. return;
  320. }
  321. // if (value.startsWith("0")) {
  322. // callback(new Error(rule.message));
  323. // return;
  324. // }
  325. // if (value.includes(".")) {
  326. // callback(new Error(rule.message));
  327. // return;
  328. // }
  329. !/^(0|[1-9][0-9]*)(\.\d{1})?$/.test(value) &&
  330. callback(new Error(rule.message));
  331. callback();
  332. };
  333. let validateSublistName = (rule, value, callback) => {
  334. this.nodeList = [];
  335. this.deepFirstSearch(this.getDataWay.data[0], this.nodeList);
  336. let names = this.nodeList
  337. .filter((i) => i.id != this.form.id)
  338. .map((i) => i.sublistName);
  339. if (names.includes(value)) {
  340. callback(new Error(rule.message));
  341. return;
  342. } else {
  343. callback();
  344. }
  345. };
  346. return {
  347. packageId: "",
  348. share: "",
  349. columns: [
  350. {
  351. label: "操作",
  352. prop: "cgInfos",
  353. template: true,
  354. },
  355. {
  356. label: "指标名称",
  357. prop: "sublistName",
  358. template: true,
  359. },
  360. {
  361. label: "权重%",
  362. prop: "weight",
  363. template: true,
  364. },
  365. {
  366. label: "场景数量",
  367. prop: "sceneNum",
  368. },
  369. {
  370. label: "规则名称",
  371. prop: "ruleName",
  372. },
  373. {
  374. label: "备注",
  375. prop: "remarks",
  376. },
  377. ],
  378. getDataWay: {
  379. //加载表格数据
  380. dataType: "data",
  381. // 给出根节点
  382. data: [
  383. {
  384. children: null,
  385. id: "1",
  386. share: "",
  387. packageAndRules: "",
  388. packageLevel: 1,
  389. parentId: "0", // 判断根路径的标识
  390. remarks: "",
  391. rootId: null,
  392. ruleName: "",
  393. ruleNameArrayS: [],
  394. sceneGeneralizationIds: null,
  395. sceneNaturalIds: "",
  396. sceneNum: 0,
  397. sceneStatueIds: null,
  398. sceneTrafficIds: null,
  399. seq: 0,
  400. sublistName: "一级指标",
  401. weight: 100,
  402. // 配合view-tree即elTree使用
  403. treeNode: "一级指标" + " (" + 100 + "%)",
  404. },
  405. ],
  406. },
  407. idIndex: 1, // 用做新增加点id自加,因为id为空会报错
  408. nameDiaTitle: "", // 编辑该级节点信息的dialog的title
  409. indicatorsVisible: false, // 编辑指标dialog
  410. scenarioVisible: false, // 选择场景dialog
  411. scenarioListsVisible: false, // 真实场景列表dialog
  412. form: {
  413. sublistName: "",
  414. weight: "",
  415. remarks: "",
  416. id: "",
  417. },
  418. rules: {
  419. sublistName: [
  420. { required: true, message: "请输入", trigger: "blur" },
  421. {
  422. validator: validateSublistName,
  423. message: "指标名称重复",
  424. trigger: ["blur"],
  425. },
  426. ],
  427. weight: [
  428. { required: true, message: "请输入", trigger: "blur" },
  429. {
  430. validator: validateNum,
  431. message: "请输入大不于100且最多带有一位小数的正数",
  432. trigger: ["blur"],
  433. },
  434. ],
  435. },
  436. ruleList: [],
  437. formA: {
  438. sceneType: "1",
  439. ruleName: "",
  440. ruleNameArrayS: [],
  441. rulesId: "",
  442. },
  443. rulesA: {
  444. sceneType: [
  445. { required: true, message: "请选择", trigger: "change" },
  446. ],
  447. ruleNameArrayS: [
  448. { required: true, message: "请选择", trigger: "change" },
  449. ],
  450. },
  451. sceneTypeList: [
  452. { caption: "真实场景", code: "1" },
  453. { caption: "泛化场景", code: "2" },
  454. ],
  455. props: {
  456. multiple: false,
  457. label: "name",
  458. value: "code",
  459. },
  460. nodeList: [], // 把当前所有节点遍历到一个扁平数组
  461. curNode: {}, // 当前操作的节点
  462. editType: "", // 点操作编辑的类型 新增or编辑
  463. checkedIdsA: [], // 交通事故列表已选
  464. checkedIdsB: [], // 自然驾驶列表已选
  465. checkedIdsC: [], // 标准法规列表已选
  466. isRoot: false, // 是否是根节点
  467. templateViewVisible: false, // 模板预览dialog
  468. treeData: [],
  469. weightErrIds: [], // 存储weightErr为false的节点id的数组
  470. generalizationVisible: false, // 泛化dialog
  471. stepActive: 1, // 泛化步骤
  472. generalizationSceneId: "", // 泛化编号
  473. generalizationId: "", // 泛化详情id
  474. genUrlType: 1, // 1为从列表跳入的模板信息,2为泛化后的详情
  475. maxSceneCount: 0, // 可创建的最大场景数量
  476. originRuleList: [], // 原版的res.info
  477. };
  478. },
  479. computed: {
  480. ...mapState(["roleCode"]),
  481. generalizationDiaTitle() {
  482. if(this.stepActive != 2) {
  483. return "泛化场景"
  484. } else {
  485. return "泛化场景 " + this.generalizationSceneId
  486. }
  487. }
  488. },
  489. methods: {
  490. viewTree() {
  491. this.templateViewVisible = true;
  492. this.nodeList = [];
  493. // 遍历当前树 拿到所有节点的平行展开数组
  494. this.deepFirstSearch(this.getDataWay.data[0], this.nodeList);
  495. let arr = this.nodeList;
  496. this.nodeList = [];
  497. this.weightErrIds = [];
  498. arr.forEach((i) => {
  499. if (i.treeNode) {
  500. i.topic = i.treeNode;
  501. } else {
  502. i.topic = i.sublistName + " (" + i.weight + "%)";
  503. }
  504. i.parentid = i.parentId;
  505. if (i.parentId === "0") {
  506. i.isroot = true;
  507. } else {
  508. i.expanded = true;
  509. }
  510. if (i.weightErr) this.weightErrIds.push(i.id);
  511. });
  512. this.treeData = arr;
  513. },
  514. delRow(row) {
  515. this.$confirm("确认是否删除?", "提示", {
  516. confirmButtonText: "确定",
  517. cancelButtonText: "取消",
  518. type: "warning",
  519. }).then(() => {
  520. this.nodeList = [];
  521. this.deepFirstSearch(
  522. this.getDataWay.data[0],
  523. this.nodeList,
  524. row.parentId
  525. );
  526. let index = this.curNode.children.findIndex(
  527. (i) => i.id === row.id
  528. );
  529. this.curNode.children.splice(index, 1);
  530. let node = null;
  531. if (this.curNode.children && this.curNode.children.length > 0) {
  532. node = this.curNode.children[0];
  533. } else {
  534. // 解决删除该节点前,其父节点只有一个孩子时,场景数量还会存在的问题
  535. this.curNode.sceneNum = 0;
  536. node = this.curNode;
  537. }
  538. if (node.parentId != "0") {
  539. this.sceneNumUpdate(node);
  540. } else {
  541. this.curNode.sceneNum = 0;
  542. }
  543. this.checkWeightValidate();
  544. });
  545. },
  546. // 编辑该级节点信息
  547. editRow(row) {
  548. this.nameDiaTitle = "编辑指标";
  549. this.editType = "edit";
  550. this.indicatorsVisible = true;
  551. if (row.parentId === "0") {
  552. this.isRoot = true;
  553. } else {
  554. this.isRoot = false;
  555. }
  556. this.form.sublistName = row.sublistName;
  557. this.form.weight = row.weight;
  558. this.form.remarks = row.remarks;
  559. this.form.id = row.id;
  560. this.curNode = row;
  561. },
  562. // 增加该级节点的子节点
  563. addIndicators(row) {
  564. this.nameDiaTitle = "添加指标";
  565. this.editType = "add";
  566. this.indicatorsVisible = true;
  567. this.curNode = row;
  568. },
  569. // 添加场景
  570. addScenario(row) {
  571. this.curNode = row;
  572. if (row.sceneGeneralizationIds) {
  573. this.formA.sceneType = "2";
  574. } else {
  575. this.formA.sceneType = "1";
  576. }
  577. if (row.packageAndRules) {
  578. this.formA.rulesId = row.packageAndRules;
  579. this.formA.ruleName = row.ruleName;
  580. this.formA.ruleNameArrayS = row.ruleNameArrayS;
  581. // this.formA.ruleName =
  582. // this.originRuleList.find(
  583. // (i) => i.rulesId === row.packageAndRules
  584. // ).ruleName || "";
  585. }
  586. this.scenarioVisible = true;
  587. },
  588. // 操作节点dialog的确定
  589. indicatorsConfirm() {
  590. this.$refs.form.validate((valid) => {
  591. if (valid) {
  592. if (this.editType == "edit") {
  593. // 编辑节点
  594. this.curNode.sublistName = this.form.sublistName;
  595. this.curNode.weight = this.form.weight;
  596. this.curNode.remarks = this.form.remarks;
  597. // 为了预览展示
  598. this.curNode.treeNode =
  599. this.form.sublistName +
  600. " (" +
  601. this.form.weight +
  602. "%)";
  603. } else {
  604. // 新增节点
  605. ++this.idIndex;
  606. let node = {
  607. children: null,
  608. id: this.idIndex + "",
  609. packageAndRules: "",
  610. packageLevel: 1,
  611. parentId: this.curNode.id || "",
  612. remarks: this.form.remarks || "",
  613. rootId: this.packageId,
  614. ruleName: "",
  615. ruleNameArrayS: [],
  616. sceneGeneralizationIds: null,
  617. sceneNaturalIds: "",
  618. sceneNum: 0,
  619. sceneStatueIds: null,
  620. sceneTrafficIds: null,
  621. seq: 0,
  622. sublistName: this.form.sublistName,
  623. weight: this.form.weight,
  624. treeNode:
  625. this.form.sublistName +
  626. " (" +
  627. this.form.weight +
  628. "%)",
  629. };
  630. if (!this.curNode.children) {
  631. this.curNode.children = [];
  632. }
  633. this.curNode.children.push(node);
  634. }
  635. this.nodeList = [];
  636. // 遍历当前树 拿到所有节点的平行展开数组
  637. this.deepFirstSearch(
  638. this.getDataWay.data[0],
  639. this.nodeList
  640. );
  641. // console.log(this.getDataWay.data);
  642. this.checkWeightValidate();
  643. this.indicatorsCancel();
  644. }
  645. });
  646. },
  647. // 操作节点dialog的取消
  648. indicatorsCancel() {
  649. this.$refs.form.resetFields();
  650. this.form.sublistName = "";
  651. this.form.weight = "";
  652. this.form.remarks = "";
  653. this.form.id = "";
  654. this.curNode = {};
  655. this.indicatorsVisible = false;
  656. },
  657. // 场景分类dialog的确定 下一步
  658. scenarioConfirm() {
  659. this.$refs.formA.validate((valid) => {
  660. if (valid) {
  661. this.scenarioVisible = false;
  662. // 真实场景
  663. if (this.formA.sceneType === "1") {
  664. this.scenarioListsVisible = true;
  665. // 切换到第一个tab页并清空所有tab页中查询条件
  666. this.$nextTick(() => {
  667. this.$refs.realScene.activeName = "1";
  668. this.$refs.realScene.doResetA();
  669. this.$refs.realScene.doResetB();
  670. this.$refs.realScene.doResetC();
  671. // 把选中数据对应的ids组分别传入tabs中,用于后续操作数据进行存储
  672. if (this.curNode.sceneTrafficIds) {
  673. this.$refs.realScene.checkedIdsA =
  674. this.curNode.sceneTrafficIds.split(",");
  675. }
  676. if (this.curNode.sceneNaturalIds) {
  677. this.$refs.realScene.checkedIdsB =
  678. this.curNode.sceneNaturalIds.split(",");
  679. }
  680. if (this.curNode.sceneStatueIds) {
  681. this.$refs.realScene.checkedIdsC =
  682. this.curNode.sceneStatueIds.split(",");
  683. }
  684. });
  685. } else {
  686. // 泛化场景
  687. if (this.curNode.exampleId) {
  688. // 进详情
  689. this.genUrlType = 2;
  690. this.stepActive = 2;
  691. } else {
  692. // 进列表
  693. this.genUrlType = 1;
  694. this.stepActive = 1;
  695. }
  696. this.generalizationVisible = true;
  697. }
  698. }
  699. });
  700. },
  701. // 场景分类dialog的取消
  702. scenarioCancel() {
  703. this.$refs.formA.resetFields();
  704. this.formA.sceneType = "1";
  705. this.formA.ruleName = "";
  706. this.formA.ruleNameArrayS = [];
  707. this.formA.rulesId = "";
  708. this.scenarioVisible = false;
  709. this.curNode = {};
  710. },
  711. // 选择真实场景dialog的确定
  712. scenarioListsConfirm() {
  713. // 获取选中的数据
  714. this.checkedIdsA = this.$refs.realScene.checkedIdsA;
  715. this.checkedIdsB = this.$refs.realScene.checkedIdsB;
  716. this.checkedIdsC = this.$refs.realScene.checkedIdsC;
  717. this.curNode.packageAndRules = this.formA.rulesId;
  718. this.curNode.ruleName = this.formA.ruleName;
  719. this.curNode.ruleNameArrayS = this.formA.ruleNameArrayS;
  720. this.curNode.sceneNum =
  721. this.checkedIdsA.length +
  722. this.checkedIdsB.length +
  723. this.checkedIdsC.length;
  724. // 选择场景总数为0 则去掉对应的规则名称和id
  725. if (this.curNode.sceneNum === 0) {
  726. this.curNode.packageAndRules = "";
  727. this.curNode.ruleName = "";
  728. this.curNode.ruleNameArrayS = [];
  729. } else {
  730. this.curNode.packageAndRules = this.formA.rulesId;
  731. this.curNode.ruleName = this.formA.ruleName;
  732. this.curNode.ruleNameArrayS = this.formA.ruleNameArrayS;
  733. }
  734. // 选中数据分别传入对应的ids组
  735. this.curNode.sceneTrafficIds = this.checkedIdsA.join(",");
  736. this.curNode.sceneNaturalIds = this.checkedIdsB.join(",");
  737. this.curNode.sceneStatueIds = this.checkedIdsC.join(",");
  738. // 清空泛化场景的数据
  739. this.curNode.exampleId = "";
  740. this.curNode.sceneGeneralizationIds = "";
  741. this.curNode.templateId = "";
  742. this.nodeList = [];
  743. // 遍历当前树 拿到所有节点的平行展开数组
  744. this.deepFirstSearch(this.getDataWay.data[0], this.nodeList);
  745. this.sceneNumUpdate(this.curNode);
  746. this.scenarioListsCancel();
  747. },
  748. // 选择真实场景dialog的取消
  749. scenarioListsCancel() {
  750. this.scenarioCancel();
  751. // 清空选中行数据
  752. this.$refs.realScene.$refs.tableA.$refs.ListTable.clearSelection();
  753. this.$refs.realScene.$refs.tableB.$refs.ListTable.clearSelection();
  754. this.$refs.realScene.$refs.tableC.$refs.ListTable.clearSelection();
  755. this.$refs.realScene.checkedIdsA = [];
  756. this.$refs.realScene.checkedIdsB = [];
  757. this.$refs.realScene.checkedIdsC = [];
  758. this.$refs.realScene.checkedArrA = [];
  759. this.$refs.realScene.checkedArrB = [];
  760. this.$refs.realScene.checkedArrC = [];
  761. this.$refs.realScene.selectedA = false;
  762. this.$refs.realScene.selectedB = false;
  763. this.$refs.realScene.selectedC = false;
  764. this.scenarioListsVisible = false;
  765. },
  766. // 泛化-上一步
  767. generalizationPrev() {
  768. this.stepActive = 1;
  769. },
  770. // 泛化-下一步
  771. generalizationNext() {
  772. let arr = [];
  773. if (
  774. this.$refs.generalizationList &&
  775. this.$refs.generalizationList.checkedArr
  776. ) {
  777. arr = this.$refs.generalizationList.checkedArr;
  778. } else {
  779. return;
  780. }
  781. if (arr.length === 0) {
  782. this.$message.warning("请先选择一条数据");
  783. return;
  784. } else if (arr.length > 1) {
  785. this.$message.warning("只能选择一条数据");
  786. return;
  787. }
  788. this.generalizationId = arr[0].id;
  789. this.generalizationSceneId = arr[0].sceneId;
  790. this.genUrlType = 1;
  791. this.stepActive = 2;
  792. },
  793. // 泛化-完成按钮
  794. generalizationConfirm() {
  795. this.$refs.generalizationDetail.done();
  796. },
  797. // 泛化-取消
  798. generalizationCancel() {
  799. this.$refs.formA.resetFields();
  800. this.formA.ruleName = "";
  801. this.formA.ruleNameArrayS = [];
  802. this.formA.rulesId = "";
  803. this.generalizationVisible = false;
  804. },
  805. // 开始泛化
  806. generalizationBegin() {
  807. this.generalizationCancel();
  808. this.curNode.sceneNum = "泛化中";
  809. this.curNode = {};
  810. },
  811. // 泛化完成回调
  812. generalizationDone(info, obj, isSuccess = true) {
  813. this.nodeList = [];
  814. // 遍历当前树 拿到所有节点的平行展开数组
  815. this.deepFirstSearch(this.getDataWay.data[0], this.nodeList);
  816. let node = this.nodeList.find((i) => i.id === obj.curId);
  817. if (node) {
  818. if (isSuccess) {
  819. node.exampleId = info.exampleId;
  820. node.sceneGeneralizationIds = info.sceneGeneralizationIds;
  821. node.sceneNum = info.sceneNum;
  822. node.id = info.sublistId;
  823. node.templateId = info.templateId;
  824. node.packageAndRules = obj.rulesId;
  825. node.ruleName = obj.ruleName;
  826. node.ruleNameArrayS = obj.ruleNameArrayS;
  827. } else {
  828. // 若泛化失败则清空对应字段
  829. node.exampleId = "";
  830. node.sceneGeneralizationIds = "";
  831. node.sceneNum = 0;
  832. node.templateId = "";
  833. node.packageAndRules = "";
  834. node.ruleName = "";
  835. node.ruleNameArrayS = [];
  836. }
  837. // 清空真实场景的数据
  838. node.sceneTrafficIds = "";
  839. node.sceneNaturalIds = "";
  840. node.sceneStatueIds = "";
  841. this.sceneNumUpdate(node);
  842. }
  843. },
  844. // 更换模板
  845. changeTemplate() {
  846. this.stepActive = 1;
  847. },
  848. // 校验权重
  849. checkWeightValidate() {
  850. this.allRowWeightErrFalse(this.getDataWay.data[0]);
  851. let ids = [];
  852. for (let index = 0; index < this.nodeList.length; index++) {
  853. const element = this.nodeList[index];
  854. if (element.children && element.children.length > 0) {
  855. let total = 0;
  856. let arr = [];
  857. element.children.forEach((item) => {
  858. total += +this.nodeList.find((i) => i.id === item.id)
  859. .weight;
  860. arr.push(item.id);
  861. });
  862. if (total != 100) {
  863. ids.push(...arr);
  864. }
  865. }
  866. }
  867. this.rowWeightErrTrue(this.getDataWay.data[0], ids);
  868. },
  869. // 通过深度优先找节点
  870. deepFirstSearch(node, nodeList, id) {
  871. if (node) {
  872. // 有id则把对应节点赋给当前操作节点
  873. if (id && node.id === id) {
  874. this.curNode = node;
  875. }
  876. nodeList.push(node);
  877. var children = node.children;
  878. if (children) {
  879. for (var i = 0; i < children.length; i++)
  880. //每次递归的时候将 需要遍历的节点 和 节点所存储的数组传下去
  881. this.deepFirstSearch(children[i], nodeList, id);
  882. }
  883. }
  884. return nodeList;
  885. },
  886. // 使全部节点 weightErr 为 false
  887. allRowWeightErrFalse(node) {
  888. if (node) {
  889. node.weightErr = false;
  890. var children = node.children;
  891. if (children) {
  892. for (var i = 0; i < children.length; i++)
  893. this.allRowWeightErrFalse(children[i]);
  894. }
  895. }
  896. },
  897. // 使部分节点 weightErr 为 true
  898. rowWeightErrTrue(node, arr) {
  899. if (node) {
  900. if (arr.includes(node.id)) {
  901. node.weightErr = true;
  902. }
  903. var children = node.children;
  904. if (children) {
  905. for (var i = 0; i < children.length; i++)
  906. this.rowWeightErrTrue(children[i], arr);
  907. }
  908. }
  909. },
  910. save(isAdd) {
  911. this.nodeList = [];
  912. this.deepFirstSearch(this.getDataWay.data[0], this.nodeList);
  913. for (let index = 0; index < this.nodeList.length; index++) {
  914. const element = this.nodeList[index];
  915. if (element.sceneNum === "泛化中") {
  916. this.$message.error("存在泛化中场景,请稍后进行保存");
  917. return;
  918. }
  919. if (element.sceneNum == 0) {
  920. this.$message.error("场景数量不能为0");
  921. return;
  922. }
  923. if (this.roleCode != "0" && this.roleCode != "1") {
  924. if (element.sceneNum > this.maxSceneCount) {
  925. this.$message.error(
  926. `场景数量不能超过${this.maxSceneCount}`
  927. );
  928. return;
  929. }
  930. }
  931. if (element.children && element.children.length > 0) {
  932. let total = 0;
  933. let arr = [];
  934. element.children.forEach((item) => {
  935. total += +this.nodeList.find((i) => i.id === item.id)
  936. .weight;
  937. arr.push(item.sublistName);
  938. });
  939. if (total != 100) {
  940. this.$message.error(
  941. `${arr.join(",")}等权重相加应为100`
  942. );
  943. return;
  944. }
  945. }
  946. }
  947. if (isAdd || !this.$route.query.packageId) {
  948. // 另存为或新增页面
  949. this.getDataWay.data[0].packageLevel = 1;
  950. } else {
  951. this.getDataWay.data[0].packageLevel = 0;
  952. }
  953. this.getDataWay.data[0].share = this.share;
  954. this.$axios({
  955. method: "post",
  956. url: this.$api.sceneLibrary.saveScenePackage,
  957. data: {
  958. params: this.getDataWay.data,
  959. },
  960. }).then((res) => {
  961. if (res.code == 200) {
  962. this.$message.success("保存成功");
  963. this.cancel();
  964. } else {
  965. this.$message.error(res.message || "保存失败");
  966. }
  967. });
  968. },
  969. cancel() {
  970. this.$router.replace({
  971. path: "/scenarioTestPackageManagementList",
  972. });
  973. },
  974. async getRuleList() {
  975. await this.$axios({
  976. method: "post",
  977. url: this.$api.sceneLibrary.queryCsbNew,
  978. data: {},
  979. }).then((res) => {
  980. if (res.code == 200 && res.info) {
  981. this.originRuleList = res.info;
  982. // let arr = [];
  983. // res.info.forEach((i, index) => {
  984. // arr[index] = Object.assign({}, i);
  985. // });
  986. // arr.forEach((i) => {
  987. // if (i.share === "1") i.ruleName = i.ruleName + "(公有)";
  988. // });
  989. // this.ruleList = arr;
  990. this.ruleList = res.info;
  991. } else {
  992. this.$message.error(res.message || "获取评分规则列表失败");
  993. }
  994. });
  995. },
  996. ruleSelChange(v) {
  997. let item = this.$refs.cascader.getCheckedNodes(true)[0].data.vo;
  998. this.formA.ruleName = item.ruleName;
  999. this.formA.rulesId = item.rulesId;
  1000. // this.formA.ruleName = this.originRuleList.find(
  1001. // (i) => i.rulesId === val
  1002. // ).ruleName;
  1003. },
  1004. // 场景数量更新
  1005. sceneNumUpdate(curNode) {
  1006. let node = this.nodeList.find((i) => i.id === curNode.parentId);
  1007. let sceneNum = 0;
  1008. node.children.forEach((i) => {
  1009. i.sceneNum != "泛化中" ? (sceneNum += i.sceneNum) : null;
  1010. });
  1011. node.sceneNum = sceneNum;
  1012. if (node.parentId === "0") {
  1013. return;
  1014. }
  1015. this.sceneNumUpdate(node);
  1016. },
  1017. templateViewClose() {
  1018. this.templateViewVisible = false;
  1019. this.treeData = [];
  1020. },
  1021. getCount() {
  1022. this.$axios({
  1023. method: "post",
  1024. url: this.$api.sceneLibrary.getSceneParam,
  1025. data: {},
  1026. }).then((res) => {
  1027. if (res.code == 200 && res.info) {
  1028. this.maxSceneCount = res.info.numScenePerPackage || 0;
  1029. } else {
  1030. this.$message.error(res.message || "获取信息失败");
  1031. }
  1032. });
  1033. },
  1034. },
  1035. mounted() {
  1036. if (this.$route.query.packageId) {
  1037. this.packageId = this.$route.query.packageId;
  1038. this.share = this.$route.query.share;
  1039. if (this.packageId) {
  1040. this.$axios({
  1041. method: "post",
  1042. url: this.$api.sceneLibrary.queryScenePackageSublistList,
  1043. data: {
  1044. packageId: this.packageId,
  1045. },
  1046. }).then((res) => {
  1047. if (res.code == 200 && res.info) {
  1048. this.getDataWay.data = res.info;
  1049. } else {
  1050. this.$message.error(res.message || "获取信息失败");
  1051. }
  1052. });
  1053. }
  1054. }
  1055. this.getRuleList();
  1056. if (this.roleCode != "0" && this.roleCode != "1") {
  1057. this.getCount();
  1058. }
  1059. },
  1060. };
  1061. </script>
  1062. <style lang='less' scoped>
  1063. .scenePacketListPanel {
  1064. padding: 30px;
  1065. .viewBox {
  1066. padding: 0 10px 10px;
  1067. }
  1068. .tips {
  1069. padding: 10px 0 10px 18px;
  1070. font-size: 12px;
  1071. color: @gray;
  1072. }
  1073. .scenarioListsDia,
  1074. .generalizationDia {
  1075. /deep/ .el-dialog__body {
  1076. padding: 20px 60px;
  1077. }
  1078. }
  1079. .generalizationDia {
  1080. /deep/ .el-dialog__body {
  1081. position: relative;
  1082. .changeBtn {
  1083. position: absolute;
  1084. top: 20px;
  1085. right: 60px;
  1086. }
  1087. }
  1088. }
  1089. .el-form {
  1090. .el-input,
  1091. .el-select,
  1092. .el-cascader {
  1093. width: 100%;
  1094. }
  1095. .el-cascader {
  1096. height: 32px;
  1097. line-height: 32px;
  1098. }
  1099. .el-select /deep/ .el-input, .el-cascader /deep/ .el-input {
  1100. width: 100%;
  1101. }
  1102. }
  1103. .btns {
  1104. padding: 30px 0;
  1105. text-align: center;
  1106. }
  1107. .templateViewDia {
  1108. /deep/ .el-dialog {
  1109. // max-height: 80%;
  1110. height: calc(100% - 12vh - 15px);
  1111. margin-top: 6vh !important;
  1112. // height: 600px;
  1113. // overflow: auto;
  1114. // overflow: hidden;
  1115. .el-dialog__body {
  1116. // height: 100%;
  1117. height: calc(100% - 130px);
  1118. overflow: auto;
  1119. &.toCenter {
  1120. display: flex;
  1121. justify-content: center;
  1122. align-items: center;
  1123. }
  1124. }
  1125. }
  1126. }
  1127. }
  1128. </style>