PropertyInfo.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. <template>
  2. <section class="property-info">
  3. <!-- 正文信息 -->
  4. <div class="part-box">
  5. <h2 class="part-box-title">{{ courseProperty.name }}</h2>
  6. <!-- <el-form
  7. class="part-filter-form"
  8. :inline="true"
  9. :model="courseProperty"
  10. label-position="right"
  11. label-width="100px"
  12. >
  13. <el-form-item label="课程名称">
  14. <el-select
  15. v-model="courseProperty.courseId"
  16. filterable
  17. :remote-method="getCourses"
  18. remote
  19. clearable
  20. :disabled="true"
  21. >
  22. <el-option
  23. v-for="item in courseInfoSelect"
  24. :key="item.courseId"
  25. :label="item.courseInfo"
  26. :value="item.courseId"
  27. >
  28. </el-option>
  29. </el-select>
  30. </el-form-item>
  31. </el-form> -->
  32. <div class="part-box-action">
  33. <div class="icon-btn-group">
  34. <svg-btn name="xinzeng">新增同级</svg-btn>
  35. <svg-btn name="xinzeng">新增子级</svg-btn>
  36. <svg-btn name="bianji">编辑</svg-btn>
  37. <svg-btn name="shanchu">删除</svg-btn>
  38. <svg-btn name="shangjiantou">上移</svg-btn>
  39. <svg-btn name="xiajiantou">下移</svg-btn>
  40. </div>
  41. <!-- <div>
  42. <el-button
  43. type="primary"
  44. icon="icon icon-plus-white"
  45. @click="insertParent"
  46. >新增一级</el-button
  47. >
  48. <el-button
  49. type="primary"
  50. icon="icon icon-plus-white"
  51. :disabled="showSonButtton"
  52. @click="insertSon"
  53. >新增二级</el-button
  54. >
  55. <el-button
  56. type="primary"
  57. plain
  58. icon="icon icon-edit"
  59. :disabled="showButton"
  60. @click="updateProperty"
  61. >编辑</el-button
  62. >
  63. <el-button
  64. type="danger"
  65. plain
  66. icon="icon icon-delete"
  67. :disabled="!multipleSelection.length"
  68. @click="deleteProperty"
  69. >删除</el-button
  70. >
  71. <el-button
  72. type="primary"
  73. plain
  74. icon="icon icon-import"
  75. :disabled="showMoveButtton"
  76. @click="moveUp"
  77. >上移</el-button
  78. >
  79. <el-button
  80. type="primary"
  81. plain
  82. icon="icon icon-export"
  83. :disabled="showMoveButtton"
  84. @click="moveDown"
  85. >下移</el-button
  86. >
  87. </div> -->
  88. <div>
  89. <el-button type="danger" plain icon="icon icon-back" @click="back"
  90. >返回</el-button
  91. >
  92. </div>
  93. </div>
  94. </div>
  95. <div class="part-box property-box">
  96. <el-tree
  97. ref="PropertyTree"
  98. class="property-tree"
  99. :data="treeData"
  100. node-key="id"
  101. :props="defaultProps"
  102. :default-expanded-keys="ids"
  103. highlight-current
  104. show-checkbox
  105. :check-strictly="true"
  106. @node-click="handleNodeClick"
  107. @check="checkChange"
  108. ><span
  109. slot-scope="{ data }"
  110. :class="{ 'node-level-one': !data.parentId }"
  111. >
  112. <span>{{ data.name }}({{ data.code }})</span>
  113. </span></el-tree
  114. >
  115. </div>
  116. <el-dialog
  117. :title="title"
  118. :visible.sync="propertyDialog"
  119. :modal="true"
  120. width="620px"
  121. :close-on-click-modal="false"
  122. :close-on-press-escape="false"
  123. append-to-body
  124. custom-class="side-dialog"
  125. @close="closeModel"
  126. >
  127. <el-form
  128. ref="propertyForm"
  129. :model="propertyForm"
  130. :rules="rules"
  131. inline-message
  132. class="form-tight"
  133. label-width="100px"
  134. >
  135. <el-row>
  136. <el-form-item label="编号" prop="code">
  137. <el-input
  138. v-model="propertyForm.code"
  139. auto-complete="off"
  140. class="dialog-input-width"
  141. disabled
  142. ></el-input>
  143. </el-form-item>
  144. </el-row>
  145. <el-row v-if="isFirstLev()">
  146. <el-form-item label="一级名称" prop="name">
  147. <el-input
  148. v-model="propertyForm.name"
  149. auto-complete="off"
  150. class="dialog-input-width"
  151. ></el-input>
  152. </el-form-item>
  153. </el-row>
  154. <el-row v-if="isSecondLev()">
  155. <el-form-item label="二级名称" prop="name">
  156. <el-input
  157. v-model="propertyForm.name"
  158. auto-complete="off"
  159. class="dialog-input-width"
  160. ></el-input>
  161. </el-form-item>
  162. </el-row>
  163. <el-row>
  164. <el-form-item label="名称备注">
  165. <el-input
  166. v-model="propertyForm.remark"
  167. auto-complete="off"
  168. :maxlength="100"
  169. ></el-input>
  170. </el-form-item>
  171. </el-row>
  172. </el-form>
  173. <div slot="footer" class="dialog-footer">
  174. <el-button type="primary" @click="submit">确定</el-button>
  175. <el-button type="danger" plain @click="closeModel">取消</el-button>
  176. </div>
  177. </el-dialog>
  178. </section>
  179. </template>
  180. <script>
  181. import { QUESTION_API } from "@/constants/constants";
  182. import { mapState } from "vuex";
  183. export default {
  184. data() {
  185. return {
  186. courseProperty: {
  187. name: "",
  188. courseId: "",
  189. },
  190. courseList: [],
  191. ids: [],
  192. loading: false,
  193. propertyDialog: false,
  194. propertyForm: {
  195. id: "",
  196. code: "",
  197. name: "",
  198. parentId: "",
  199. number: "",
  200. coursePropertyId: "",
  201. remark: "",
  202. },
  203. curProperty: {
  204. id: "",
  205. code: "",
  206. name: "",
  207. parentId: "",
  208. number: "",
  209. coursePropertyId: "",
  210. remark: "",
  211. },
  212. multipleSelection: [],
  213. showButton: true,
  214. showSonButtton: true,
  215. showMoveButtton: true,
  216. treeData: [],
  217. defaultProps: {
  218. children: "propertyList",
  219. },
  220. title: "新增属性",
  221. rules: {
  222. code: [
  223. {
  224. required: true,
  225. message: "请输入编码",
  226. trigger: "blur",
  227. },
  228. {
  229. max: 100,
  230. message: "编码最多100个字符",
  231. trigger: "blur",
  232. },
  233. ],
  234. name: [
  235. {
  236. required: true,
  237. message: "请输入名称",
  238. trigger: "blur",
  239. },
  240. {
  241. max: 100,
  242. message: "名称最多100个字符",
  243. trigger: "blur",
  244. },
  245. ],
  246. },
  247. };
  248. },
  249. computed: {
  250. ...mapState({ user: (state) => state.user }),
  251. courseInfoSelect() {
  252. var courseList = [];
  253. for (var i = 0; i < this.courseList.length; i++) {
  254. var courseInfo = {
  255. courseInfo:
  256. this.courseList[i].name + "(" + this.courseList[i].code + ")",
  257. courseId: this.courseList[i].id,
  258. };
  259. courseList.push(courseInfo);
  260. }
  261. return courseList;
  262. },
  263. IS_ASSIGN_TEACHER() {
  264. // 命题老师
  265. return this.user.roleList.some(
  266. (item) => item.roleCode === "ASSIGN_TEACHER"
  267. );
  268. },
  269. },
  270. created() {
  271. // this.coursePropertyId = this.$route.params.id;
  272. this.courseProperty.courseId = this.$route.params.id;
  273. this.searchProperty();
  274. },
  275. mounted() {
  276. setTimeout(() => {
  277. this.$store.commit("UPDATE_CURRENT_PATHS", [
  278. "课程管理",
  279. "知识点",
  280. "属性结构",
  281. ]);
  282. }, 200);
  283. },
  284. methods: {
  285. disAllBtn() {
  286. this.showButton = true;
  287. this.showSonButtton = true;
  288. this.showMoveButtton = true;
  289. },
  290. isFirstLev() {
  291. if (this.propertyForm.parentId == "0") {
  292. return true;
  293. } else {
  294. return false;
  295. }
  296. },
  297. isSecondLev() {
  298. if (this.propertyForm.parentId && this.propertyForm.parentId != "0") {
  299. return true;
  300. } else {
  301. return false;
  302. }
  303. },
  304. closeModel() {
  305. this.propertyDialog = false;
  306. this.$refs.propertyForm.resetFields();
  307. },
  308. //树形节点选中
  309. handleNodeClick(object) {
  310. this.showButton = false;
  311. //判断选中节点,如果是父节点,可以新增二级
  312. if (object.parentId == "0") {
  313. this.showSonButtton = false;
  314. } else {
  315. this.showSonButtton = true;
  316. }
  317. this.showMoveButtton = false;
  318. this.curProperty = Object.assign({}, object);
  319. },
  320. checkChange(data, { checkedKeys }) {
  321. const checked = checkedKeys.includes(data.id);
  322. if (!data.propertyList || !data.propertyList.length) {
  323. this.multipleSelection = this.$refs.PropertyTree.getCheckedKeys();
  324. if (checked) return;
  325. this.multipleSelection = this.multipleSelection.filter(
  326. (id) => id !== data.parentId
  327. );
  328. this.$refs.PropertyTree.setCheckedKeys(this.multipleSelection);
  329. return;
  330. }
  331. let propsIds = [];
  332. const getPropIds = (propertyList) => {
  333. if (!propertyList || !propertyList.length) return;
  334. propertyList.forEach((item) => {
  335. propsIds.push(item.id);
  336. if (item.propertyList) getPropIds(item.propertyList);
  337. });
  338. };
  339. if (data.propertyList && data.propertyList.length) {
  340. getPropIds(data.propertyList);
  341. if (checked) {
  342. let checkedKeys = this.$refs.PropertyTree.getCheckedKeys();
  343. checkedKeys.push(...propsIds);
  344. const idSet = new Set(checkedKeys);
  345. this.multipleSelection = Array.from(idSet);
  346. this.$refs.PropertyTree.setCheckedKeys(this.multipleSelection);
  347. } else {
  348. let checkedKeys = this.$refs.PropertyTree.getCheckedKeys();
  349. this.multipleSelection = checkedKeys.filter(
  350. (item) => !propsIds.includes(item)
  351. );
  352. this.$refs.PropertyTree.setCheckedKeys(this.multipleSelection);
  353. }
  354. } else {
  355. this.multipleSelection = this.$refs.PropertyTree.getCheckedKeys();
  356. }
  357. },
  358. //查询所有课程
  359. getCourses(query) {
  360. this.courseList = [];
  361. if (query) {
  362. this.courseLoading = true;
  363. this.$http.get(QUESTION_API + "/course/" + query).then((response) => {
  364. var courseBean = response.data;
  365. this.courseList.push(courseBean);
  366. this.courseProperty.name = courseBean.name;
  367. });
  368. } else {
  369. this.courseList = [];
  370. }
  371. },
  372. //查询
  373. searchProperty() {
  374. this.loading = true;
  375. // var coursePropertyStorge = sessionStorage.getItem("courseProperty");
  376. // if (typeof coursePropertyStorge == "string") {
  377. // this.courseProperty = JSON.parse(coursePropertyStorge);
  378. this.getCourses(this.courseProperty.courseId);
  379. // }
  380. // this.$http
  381. // .get(QUESTION_API + "/property/all/" + this.coursePropertyId)
  382. // .then((response) => {
  383. // this.treeData = response.data;
  384. // for (var i = 0; i < this.treeData.length; i++) {
  385. // var property = this.treeData[i];
  386. // this.ids.push(property.id);
  387. // }
  388. // this.loading = false;
  389. // });
  390. this.$http
  391. .post(
  392. QUESTION_API +
  393. "/property/all/by/course?courseId=" +
  394. this.$route.params.id
  395. )
  396. .then((response) => {
  397. this.coursePropertyId = response.data.coursePropertyId;
  398. this.treeData = response.data.propertys;
  399. for (var i = 0; i < this.treeData.length; i++) {
  400. var property = this.treeData[i];
  401. this.ids.push(property.id);
  402. }
  403. this.loading = false;
  404. });
  405. },
  406. getPropertyCode(parentId) {
  407. this.$http
  408. .post(QUESTION_API + "/property/get_code", {
  409. rootOrgId: this.user.rootOrgId,
  410. coursePropertyId: this.coursePropertyId,
  411. parentId,
  412. })
  413. .then((response) => {
  414. this.propertyForm.code = response.data;
  415. });
  416. },
  417. //新增一级
  418. insertParent() {
  419. this.disAllBtn();
  420. this.title = "新增属性";
  421. this.propertyForm = {
  422. id: "",
  423. code: "",
  424. name: "",
  425. parentId: "0",
  426. number: "",
  427. coursePropertyId: this.coursePropertyId,
  428. remark: "",
  429. };
  430. this.propertyDialog = true;
  431. this.getPropertyCode(0);
  432. },
  433. //新增二级
  434. insertSon() {
  435. this.disAllBtn();
  436. this.title = "新增属性";
  437. //父对象id赋值
  438. this.propertyForm = {
  439. id: "",
  440. code: "",
  441. name: "",
  442. parentId: this.curProperty.id,
  443. number: "",
  444. coursePropertyId: this.coursePropertyId,
  445. remark: "",
  446. };
  447. this.propertyDialog = true;
  448. this.getPropertyCode(this.curProperty.id);
  449. },
  450. //修改
  451. updateProperty() {
  452. this.disAllBtn();
  453. this.title = "修改属性";
  454. this.propertyForm = Object.assign({}, this.curProperty);
  455. this.propertyDialog = true;
  456. },
  457. //保存
  458. async submit() {
  459. const res = await this.$refs.propertyForm.validate();
  460. if (res === false) {
  461. return;
  462. }
  463. this.$http
  464. .post(QUESTION_API + "/property/save", this.propertyForm)
  465. .then(() => {
  466. this.$notify({
  467. message: this.propertyForm.id ? "修改成功" : "新增成功",
  468. type: "success",
  469. });
  470. this.propertyDialog = false;
  471. this.searchProperty();
  472. })
  473. .catch((error) => {
  474. this.$notify({
  475. type: "error",
  476. message: error.response.data.desc,
  477. });
  478. });
  479. this.showButton = true;
  480. this.showSonButtton = true;
  481. },
  482. //删除
  483. async deleteProperty() {
  484. this.disAllBtn();
  485. const confirm = await this.$confirm("确认删除属性吗?", "提示", {
  486. type: "warning",
  487. }).catch(() => {});
  488. if (confirm !== "confirm") return;
  489. this.loading = true;
  490. const res = await this.$http
  491. .delete(
  492. QUESTION_API +
  493. "/property/delete/" +
  494. this.multipleSelection.join() +
  495. "/" +
  496. this.coursePropertyId
  497. )
  498. .catch(() => {});
  499. this.loading = false;
  500. if (!res) return;
  501. this.$notify({
  502. message: "删除成功",
  503. type: "success",
  504. });
  505. this.multipleSelection = [];
  506. this.searchProperty();
  507. this.showButton = true;
  508. this.showSonButtton = true;
  509. },
  510. //返回
  511. back() {
  512. // this.$router.push({
  513. // path: "/questions/course_property/1",
  514. // });
  515. this.$router.back();
  516. },
  517. //上移
  518. moveUp() {
  519. this.disAllBtn();
  520. this.$http
  521. .put(QUESTION_API + "/property/moveUp", this.curProperty)
  522. .then(() => {
  523. this.searchProperty();
  524. this.showMoveButtton = true;
  525. })
  526. .catch((error) => {
  527. this.$notify({
  528. type: "error",
  529. message: error.response.data.desc,
  530. });
  531. this.showMoveButtton = true;
  532. });
  533. },
  534. //下移
  535. moveDown() {
  536. this.disAllBtn();
  537. this.$http
  538. .put(QUESTION_API + "/property/moveDown", this.curProperty)
  539. .then(() => {
  540. this.searchProperty();
  541. this.showMoveButtton = true;
  542. })
  543. .catch((error) => {
  544. this.$notify({
  545. type: "error",
  546. message: error.response.data.desc,
  547. });
  548. this.showMoveButtton = true;
  549. });
  550. },
  551. },
  552. };
  553. </script>