index.vue 17 KB

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