index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. <template>
  2. <div id="commodityManageMent">
  3. <search-box-new
  4. ref="searchBox"
  5. :formData="formData"
  6. :formList="formList"
  7. @search="search"
  8. @init="init"
  9. :topType="topType"
  10. />
  11. <table-list
  12. ref="tableList"
  13. :tableSets="tableSet"
  14. :tableData="tableData"
  15. :navText="navText"
  16. @addClick="addClick"
  17. :loading="loading"
  18. @editInfo="editInfo"
  19. @openClassNum="openClassNum"
  20. rowKey="goodsId"
  21. >
  22. <!-- <template slot="customize">
  23. <el-button size="medium" @click="handelBatch(1)" type="success"
  24. >批量上架</el-button
  25. ><el-button size="medium" @click="handelBatch(0)" type="success"
  26. >批量下架</el-button
  27. ><el-button size="medium" @click="handelBatch(2)" type="warning"
  28. >批量删除</el-button
  29. >
  30. </template> -->
  31. <template slot="btn" slot-scope="props">
  32. <el-button
  33. v-if="
  34. props.scope.row.goodsType == 1 &&
  35. props.scope.row.courseNum &&
  36. props.scope.row.courseNum > 0
  37. "
  38. type="text"
  39. @click="setTeacher(props.scope.row)"
  40. >双师制设置</el-button
  41. >
  42. <el-button type="text" @click="addClick(props.scope.row, 0)"
  43. >修改</el-button
  44. >
  45. <el-button type="text" @click="changeStatus(props.scope.row)">{{
  46. props.scope.row.goodsStatus === 1 ? "下架" : "上架"
  47. }}</el-button>
  48. <el-button type="text" @click="del(props.scope.row)">删除</el-button>
  49. </template>
  50. </table-list>
  51. <pagination
  52. :total="total"
  53. :pageSize="formData.pageSize"
  54. :currentPage="formData.pageNum"
  55. @handleSizeChange="handleSizeChange"
  56. @handleCurrentChange="handleCurrentChange"
  57. />
  58. <el-dialog
  59. :visible.sync="dialogVisible"
  60. width="1000px"
  61. :show-close="false"
  62. :close-on-click-modal="false"
  63. >
  64. <div slot="title" class="hearders">
  65. <div class="leftTitle">关联商品规格</div>
  66. <div class="rightBoxs">
  67. <img
  68. src="@/assets/images/Close@2x.png"
  69. alt=""
  70. @click="dialogVisible = false"
  71. />
  72. </div>
  73. </div>
  74. <table-list
  75. :tableSets="dialogTableSet"
  76. :tableData="dialogTableData"
  77. :navText="dialogNavText"
  78. :radio.sync="tableRadio"
  79. >
  80. </table-list>
  81. <span slot="footer" class="dialog-footer">
  82. <el-button @click="dialogVisible = false">取 消</el-button>
  83. <el-button type="primary" @click="submit">确 定</el-button>
  84. </span>
  85. </el-dialog>
  86. </div>
  87. </template>
  88. <script>
  89. import searchBoxNew from "@/components/searchBoxNew";
  90. import tableList from "@/components/tableList";
  91. import pagination from "@/components/pagination";
  92. import {
  93. getGoodsSpecList,
  94. goodsUpdateSpec,
  95. goodsUpdateStatus,
  96. goodsDel,
  97. } from "@/api/resource/good";
  98. export default {
  99. name: "CommodityManageMent",
  100. components: { searchBoxNew, tableList, pagination },
  101. data() {
  102. return {
  103. loading: false, //当前表单加载是否加载动画
  104. navText: {
  105. title: "商品列表",
  106. index: 0,
  107. ch: "条",
  108. num: false,
  109. border: true,
  110. choice: true,
  111. addHide: false,
  112. changeWidth: "180px",
  113. openCheckMore: true,
  114. backFatherBtn: {
  115. status: false,
  116. title: "未定义",
  117. },
  118. },
  119. topType: true,
  120. //搜索
  121. formList: [
  122. {
  123. prop: "educationTypeId",
  124. placeholder: "教育类型",
  125. scope: "educationType",
  126. },
  127. {
  128. prop: "businessId",
  129. placeholder: "业务层次",
  130. scope: "businessLevel",
  131. edu: "educationTypeId",
  132. },
  133. {
  134. prop: "schoolId",
  135. placeholder: "院校",
  136. scope: "schoolList",
  137. edu: "educationTypeId",
  138. },
  139. {
  140. prop: "majorId",
  141. placeholder: "专业",
  142. scope: "Professional",
  143. edu: "educationTypeId",
  144. },
  145. {
  146. prop: "subjectId",
  147. placeholder: "科目",
  148. scope: "sujectType",
  149. edu: "educationTypeId",
  150. },
  151. {
  152. prop: "status",
  153. placeholder: "商品状态",
  154. scope: "select",
  155. noClear: false,
  156. options: [
  157. {
  158. label: "全部状态",
  159. value: "0,1",
  160. },
  161. {
  162. label: "有效",
  163. value: 1,
  164. },
  165. {
  166. label: "无效",
  167. value: 0,
  168. },
  169. ],
  170. },
  171. {
  172. prop: "goodsStatus",
  173. placeholder: "前台可售状态",
  174. scope: "select",
  175. options: [
  176. {
  177. label: "已上架",
  178. value: 1,
  179. },
  180. {
  181. label: "未上架",
  182. value: 0,
  183. },
  184. ],
  185. },
  186. {
  187. prop1: "validityStartTime",
  188. prop2: "validityEndTime",
  189. placeholder1: "商品有效期开始时间",
  190. placeholder2: "商品有效期结束时间",
  191. scope: "moreDataPicker",
  192. },
  193. // {
  194. // prop: "orderGoodsStatus",
  195. // placeholder: "退款状态",
  196. // scope: "select",
  197. // options: [
  198. // {
  199. // label: "已退款",
  200. // value: 1,
  201. // },
  202. // {
  203. // label: "退款中",
  204. // value: 2,
  205. // },
  206. // {
  207. // label: "拒绝退款",
  208. // value: 3,
  209. // },
  210. // ],
  211. // },
  212. {
  213. prop: "goodsName",
  214. placeholder: "请输入商品名称",
  215. },
  216. ],
  217. formData: {
  218. goodsType: "",
  219. status: "0,1",
  220. pageSize: 10,
  221. pageNum: 1,
  222. },
  223. // 表单
  224. tableSet: [
  225. {
  226. label: "商品名称",
  227. prop: "goodsName",
  228. scope: "editInfo",
  229. hidden: true,
  230. },
  231. {
  232. label: "商品编码",
  233. prop: "code",
  234. hidden: false,
  235. },
  236. {
  237. label: "专业",
  238. prop: "categoryName",
  239. hidden: true,
  240. },
  241. {
  242. label: "院校",
  243. prop: "schoolName",
  244. hidden: false,
  245. },
  246. {
  247. label: "科目",
  248. prop: "subjectNames",
  249. hidden: true,
  250. },
  251. {
  252. label: "关联商品规格",
  253. prop: "specTemplateNumber",
  254. hidden: true,
  255. scope: "aboutClassNum",
  256. },
  257. {
  258. label: "业务层次",
  259. prop1: "projectName",
  260. prop2: "businessName",
  261. hidden: false,
  262. scope: "InfoMore",
  263. },
  264. {
  265. label: "教育类型",
  266. prop: "educationName",
  267. hidden: false,
  268. },
  269. {
  270. label: "学时",
  271. prop: "classHours",
  272. hidden: true,
  273. },
  274. {
  275. label: "商品内容视图",
  276. hidden: true,
  277. scope: "treeWatch",
  278. },
  279. {
  280. label: "商品价格",
  281. prop: "standPrice",
  282. hidden: true,
  283. scope: "leftCh",
  284. ch: "¥",
  285. },
  286. {
  287. label: "商品划线价",
  288. prop: "linePrice",
  289. hidden: true,
  290. scope: "leftCh",
  291. ch: "¥",
  292. },
  293. {
  294. label: "商品状态",
  295. prop: "status",
  296. hidden: false,
  297. scope: "hasTime",
  298. },
  299. {
  300. label: "商品有效期",
  301. prop1: "validityStartTime",
  302. prop2: "validityEndTime",
  303. scope: "TimeLists",
  304. Diszing: false,
  305. hidden: true,
  306. },
  307. {
  308. label: "学习服务期",
  309. prop1: "serviceTimeType",
  310. prop2: "serviceTimeNum",
  311. prop3: "studyStartTime",
  312. prop4: "studyEndTime",
  313. scope: "studentServicePeriod",
  314. hidden: true,
  315. },
  316. {
  317. label: "供应方(服务)",
  318. prop: "supplyName",
  319. hidden: false,
  320. },
  321. {
  322. label: "最后编辑时间",
  323. prop: "updateTime",
  324. hidden: true,
  325. scope: "aTimeList",
  326. },
  327. {
  328. label: "创建时间",
  329. prop: "createTime",
  330. hidden: true,
  331. scope: "aTimeList",
  332. },
  333. {
  334. label: "可售状态",
  335. prop: "goodsStatus",
  336. hidden: true,
  337. scope: "status",
  338. },
  339. ],
  340. tableData: [], //表单数据
  341. total: 0, //一共多少条
  342. dialogVisible: false,
  343. dialogTableSet: [
  344. {
  345. label: "教育类型",
  346. prop: "educationName",
  347. hidden: true,
  348. },
  349. {
  350. label: "业务层次",
  351. prop: "businessName",
  352. hidden: true,
  353. },
  354. {
  355. label: "商品规格模板名称",
  356. prop: "name",
  357. hidden: true,
  358. },
  359. {
  360. label: "商品规格数量",
  361. prop: "specNumber",
  362. hidden: true,
  363. },
  364. ],
  365. dialogTableData: [{}],
  366. dialogNavText: {
  367. index: 0,
  368. num: false,
  369. border: true,
  370. choice: false,
  371. choiceRadio: true,
  372. radioKey: "specTemplateId",
  373. radioFixed: false,
  374. addHide: !false,
  375. tableHide: true,
  376. dontNum: true,
  377. headShow: false,
  378. backFatherBtn: {
  379. status: false,
  380. title: "未定义",
  381. },
  382. },
  383. tableRadio: "",
  384. activeGoodsId: {},
  385. };
  386. },
  387. mounted() {
  388. this.search();
  389. },
  390. activated() {
  391. this.search();
  392. },
  393. methods: {
  394. // 批量上下架
  395. handelBatch(type) {
  396. let len = this.$refs.tableList.allCheckData.length;
  397. if (!len) {
  398. return this.$message.warning("请先勾选商品");
  399. }
  400. let name = ["上架", "下架", "删除"][type];
  401. this.$confirm(`此操作将所勾选的${len}条商品${name}, 是否继续?`, "提示", {
  402. confirmButtonText: "确定",
  403. cancelButtonText: "取消",
  404. type: "warning",
  405. })
  406. .then(() => {
  407. const goodsIds = this.$refs.tableList.allCheckData.map(
  408. (item) => item.goodsId
  409. );
  410. if (type == 2) {
  411. goodsDel({
  412. status: -1,
  413. ids: goodsIds,
  414. }).then((res) => {
  415. this.$message.success("批量删除成功");
  416. this.$refs.tableList.clearMoreActive();
  417. this.search(1);
  418. });
  419. } else {
  420. goodsUpdateStatus({
  421. goodsStatus: type,
  422. goodsIds,
  423. }).then((res) => {
  424. this.$message.success(`批量${name}成功`);
  425. this.$refs.tableList.clearMoreActive();
  426. this.search(1);
  427. });
  428. }
  429. })
  430. .catch(() => {});
  431. },
  432. openClassNum(id) {
  433. this.activeGoodsId = id;
  434. let { specTemplateId } = this.tableData.find((e) => e.goodsId == id);
  435. this.tableRadio = specTemplateId || "";
  436. getGoodsSpecList(id).then((res) => {
  437. this.dialogTableData = res.data;
  438. });
  439. this.dialogVisible = true;
  440. },
  441. editInfo(v) {
  442. this.addClick(v, 0);
  443. },
  444. search(int) {
  445. this.loading = true;
  446. if (int === 1) {
  447. this.formData.pageNum = 1;
  448. }
  449. if (int === 2) {
  450. this.formData = {
  451. goodsType: "",
  452. status: "0,1",
  453. pageSize: 10,
  454. pageNum: 1,
  455. };
  456. }
  457. if (int === 3) {
  458. this.formData.pageNum = 1;
  459. }
  460. var data = JSON.parse(JSON.stringify(this.formData));
  461. if (this.formData.validityStartTime) {
  462. data.validityStartTime = data.validityStartTime / 1000;
  463. }
  464. if (this.formData.validityEndTime) {
  465. data.validityEndTime = data.validityEndTime / 1000;
  466. }
  467. this.$api
  468. .inquireGoods(data)
  469. .then((res) => {
  470. this.tableData = res.rows;
  471. this.total = res.total;
  472. this.navText.index = res.total;
  473. })
  474. .finally(() => {
  475. this.loading = false;
  476. });
  477. },
  478. init() {
  479. this.search(2);
  480. },
  481. del(v) {
  482. this.$api.gradecheckGoodsChange({ goodsId: v.goodsId }).then((res) => {
  483. if (res.data > 0) {
  484. this.$message.error("已有学员正在学习该商品,无法删除");
  485. return;
  486. } else {
  487. this.$alert(
  488. "确定删除此内容?<br />内容删除后将无法恢复,请慎重考虑",
  489. "提示",
  490. {
  491. dangerouslyUseHTMLString: true,
  492. }
  493. )
  494. .then(() => {
  495. var data = {
  496. goodsId: v.goodsId,
  497. status: -1,
  498. };
  499. this.$api.editGoods(data).then((res) => {
  500. this.$message.success("删除成功");
  501. this.search();
  502. });
  503. })
  504. .catch(() => {
  505. this.$message({
  506. type: "info",
  507. message: "已取消删除",
  508. });
  509. });
  510. }
  511. });
  512. },
  513. //双师制设置
  514. setTeacher(data) {
  515. const jump = () => {
  516. this.$router.push({
  517. path: "commoditySetTeacher",
  518. query: {
  519. id: data.goodsId,
  520. },
  521. });
  522. };
  523. const statusPage = this.$store.state.tagsView.visitedViews.some(
  524. (item) => {
  525. return item.name == "CommoditySetTeacher";
  526. }
  527. );
  528. if (statusPage) {
  529. this.$store
  530. .dispatch("tagsView/delCachedView", {
  531. name: "CommoditySetTeacher",
  532. })
  533. .then((res) => {
  534. jump();
  535. });
  536. } else {
  537. jump();
  538. }
  539. },
  540. addClick(v, int) {
  541. if (v === undefined) {
  542. this.$router.push({
  543. path: "commodityManageMentAdd",
  544. });
  545. } else {
  546. const jump = () => {
  547. this.$router.push({
  548. path: "commodityManageMentEdit",
  549. query: {
  550. id: v.goodsId,
  551. },
  552. });
  553. };
  554. const statusPage = this.$store.state.tagsView.visitedViews.some(
  555. (item) => {
  556. return item.name == "CommodityManageMentEdit";
  557. }
  558. );
  559. if (statusPage) {
  560. this.$store
  561. .dispatch("tagsView/delCachedView", {
  562. name: "CommodityManageMentEdit",
  563. })
  564. .then((res) => {
  565. jump();
  566. });
  567. } else {
  568. jump();
  569. }
  570. }
  571. },
  572. handleSizeChange(v) {
  573. this.formData.pageSize = v;
  574. this.formData.pageNum = 1;
  575. this.search();
  576. },
  577. handleCurrentChange(v) {
  578. this.formData.pageNum = v;
  579. this.search();
  580. },
  581. changeStatus(item) {
  582. var items = JSON.parse(JSON.stringify(item));
  583. items.goodsStatus = items.goodsStatus === 1 ? 0 : 1;
  584. this.$api.editGoods(items).then((res) => {
  585. if (item.goodsStatus === 1) {
  586. this.$message.success("下架成功");
  587. } else {
  588. this.$message.success("上架成功");
  589. }
  590. this.search();
  591. });
  592. },
  593. submit() {
  594. if (!this.tableRadio) {
  595. return this.$message({
  596. message: "请选择关联商品规格",
  597. type: "warning",
  598. });
  599. }
  600. goodsUpdateSpec({
  601. goodsId: this.activeGoodsId,
  602. specTemplateId: this.tableRadio,
  603. }).then((res) => {
  604. this.dialogVisible = false;
  605. this.search();
  606. });
  607. },
  608. },
  609. };
  610. </script>
  611. <style lang="less" scoped>
  612. /deep/.el-button {
  613. border-radius: 8px;
  614. }
  615. /deep/.el-dialog {
  616. border-radius: 8px;
  617. .el-dialog__header {
  618. padding: 0;
  619. .hearders {
  620. height: 40px;
  621. display: flex;
  622. align-items: center;
  623. justify-content: space-between;
  624. padding: 0px 18px 0px 20px;
  625. border-bottom: 1px solid #e2e2e2;
  626. .leftTitle {
  627. font-size: 14px;
  628. font-weight: bold;
  629. color: #2f4378;
  630. }
  631. .rightBoxs {
  632. display: flex;
  633. align-items: center;
  634. img {
  635. width: 14px;
  636. height: 14px;
  637. margin-left: 13px;
  638. cursor: pointer;
  639. }
  640. }
  641. }
  642. }
  643. .el-dialog__footer {
  644. padding: 0;
  645. .dialog-footer {
  646. padding: 0px 40px;
  647. height: 70px;
  648. border-top: 1px solid #e2e2e2;
  649. display: flex;
  650. align-items: center;
  651. justify-content: flex-end;
  652. }
  653. }
  654. }
  655. .imgBox {
  656. width: 100%;
  657. // height: 210px;
  658. border: 1px solid #e2e2e2;
  659. border-radius: 8px;
  660. padding: 8px 8px 3px;
  661. display: flex;
  662. flex-direction: column;
  663. align-items: center;
  664. .imgLabel {
  665. flex: 1;
  666. width: 100%;
  667. border: 1px dotted #e2e2e2;
  668. color: #999;
  669. font-size: 14px;
  670. cursor: pointer;
  671. border-radius: 8px;
  672. .msPhoto {
  673. display: flex;
  674. justify-content: center;
  675. align-items: center;
  676. max-width: 100%;
  677. max-height: 270px;
  678. img {
  679. max-width: 100%;
  680. max-height: 270px;
  681. }
  682. }
  683. .imgbbx {
  684. display: flex;
  685. flex-direction: column;
  686. align-items: center;
  687. justify-content: center;
  688. width: 100%;
  689. height: 100%;
  690. i {
  691. font-weight: bold;
  692. margin: 14px 0;
  693. font-size: 24px;
  694. }
  695. }
  696. }
  697. p {
  698. margin: 5px 0px;
  699. }
  700. }
  701. </style>