scenePacketList.vue 41 KB

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