index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861
  1. <template>
  2. <view class="product">
  3. <view class="top"></view>
  4. <view class="head">
  5. <view class="handle">
  6. <view class="head_left">
  7. <span class="cuIcon-back" @click="back"></span>
  8. </view>
  9. <span class="center">商品管理</span>
  10. <view class="head_right">
  11. <!-- <span class="cuIcon-search" @click="goSearch"></span> -->
  12. <view class="manage" @click="manage">
  13. {{isManage?'退出管理':'管理'}}
  14. </view>
  15. </view>
  16. </view>
  17. <view class="search">
  18. <span class="cuIcon-search"></span>
  19. <!-- <input @blur="InputBlur" :adjust-position="false" type="text" placeholder="请输入关键词" confirm-type="search"> -->
  20. <u-input v-model="productName" />
  21. </input>
  22. <view class="search_btn" @click.stop="getProductList">
  23. <span></span>搜索
  24. </view>
  25. </view>
  26. <view class="type">
  27. <view class="type_item" :class="currentIndex == index?'active':''" v-for="(item,index) in typeList" :key="index"
  28. @click="selectType(item,index)">
  29. {{item.statusName}}({{item.number}})
  30. <span class="line" v-if="currentIndex == index"></span>
  31. </view>
  32. </view>
  33. </view>
  34. <view class="list">
  35. <view class="product_item" v-for="(item,index) in productList" :key="index" @click="goDetails(item)">
  36. <view class="status">
  37. <span class="round" v-if="item.productStatus =='1'">售卖中</span>
  38. <span class="round no" v-if="item.productStatus =='0'" style="color:#666666 ;">未上架</span>
  39. <span class="audit " v-if="item.productStatus =='2'" style="color:#596ABB ;">审核中</span>
  40. <span class="reject " v-if="item.productStatus =='3'" style="color:#F55D65 ;">未通过</span>
  41. <span class="line"></span>
  42. <span v-if="item.saleStartDate">{{item.saleStartDate.slice(0,10)}}-{{item.saleEndDate.slice(0,10)}}</span>
  43. <!-- <span>已售:{{item.num}}</span>
  44. <span>库存:{{item.inventory}}</span> -->
  45. </view>
  46. <view class="details">
  47. <view class="img">
  48. <image :src="item.productImage" mode=""></image>
  49. </view>
  50. <view class="data">
  51. <span>{{item.productName}}</span>
  52. <!-- <span>售卖时间:{{item.time}}</span> -->
  53. <view class="repertory">库存:不限 <span></span> 销量:{{item.soldQuantity}}</view>
  54. <view class="price">
  55. <span style="font-size: 22rpx;margin: 0px;">¥</span>{{item.soldPrice}}
  56. <span style="color:#999 ;font-size: 22rpx; text-decoration: line-through;">¥{{item.price}}</span>
  57. </view>
  58. </view>
  59. <view class="tag" v-if="isManage" @click.stop="select(item)">
  60. <!-- <span>组合套餐</span> -->
  61. <!-- <span class="frame"></span> -->
  62. <image src="/static/product/select.png" mode="" v-if="item.select"></image>
  63. <image src="/static/product/round.png" mode="" v-else></image>
  64. </view>
  65. </view>
  66. <view class="btn_box">
  67. <view class="delist" @click.stop="sell(item)" v-if="item.productStatus==0">
  68. 上架
  69. </view>
  70. <view class="delist" @click.stop="delist(item)" v-if="item.productStatus==1">
  71. 下架
  72. </view>
  73. <view class="edit delist" @click.stop="edit(item)">
  74. 编辑
  75. </view>
  76. </view>
  77. </view>
  78. </view>
  79. <view class="creat">
  80. <view class="operate" v-if="isManage">
  81. <view class="all" @click="allSelect">
  82. <image src="/static/product/select.png" mode="" v-if="isAll"></image>
  83. <image src="/static/product/round.png" mode="" v-else></image>
  84. 全选
  85. </view>
  86. <view class="delete" @click="remove">删除</view>
  87. <view class="delete delist" @click="deletes">下架</view>
  88. </view>
  89. <view class="btn" @click="creatProduct" v-else>
  90. <image src="/static/product/product.png" mode=""></image>
  91. 创建商品
  92. </view>
  93. </view>
  94. <view class="popup" v-if="isDelete">
  95. <view class="content">
  96. <view class="title">
  97. <span>删除商品</span>
  98. </view>
  99. <view class="center">
  100. <image src="/static/index/close.png" mode="" v-if="canBeDelete"></image>
  101. <image src="/static/product/error.png" mode="" v-else></image>
  102. <view class="error" v-if="canBeDelete">
  103. 确定要删除?
  104. </view>
  105. <view class="error" v-else>
  106. 当前门店还存在有效服务券<br />
  107. <span style="margin-top: 12rpx;">暂时无法关闭门店</span>
  108. </view>
  109. </view>
  110. <view class="sub" @click="isSuccess = false">
  111. <view class="button">
  112. 确定
  113. </view>
  114. </view>
  115. </view>
  116. </view>
  117. </view>
  118. </template>
  119. <script>
  120. export default {
  121. data() {
  122. return {
  123. isManage: false,
  124. currentIndex: 0,
  125. productStatus: 0, //商品状态,默认1售卖中,0未上架,2审核中,3未通过
  126. isAll: false,
  127. isDelete: false,
  128. canBeDelete: true,
  129. productName: '',
  130. typeList: [{
  131. type: '待上架',
  132. productStatus: 0
  133. },
  134. {
  135. type: '售卖中',
  136. productStatus: 1
  137. },
  138. {
  139. type: '审核中',
  140. productStatus: 2
  141. },
  142. {
  143. type: '未通过',
  144. productStatus: 3
  145. }
  146. ],
  147. productList: [],
  148. merchantId: '',
  149. productHandleList: []
  150. }
  151. },
  152. methods: {
  153. //返回
  154. back() {
  155. uni.switchTab({
  156. url: '/pages/index/index'
  157. })
  158. },
  159. handleClear() {
  160. this.getProductList()
  161. // 这里可以添加其他逻辑
  162. },
  163. //切换分类
  164. selectType(item, index) {
  165. if (!this.isManage) {
  166. this.currentIndex = index
  167. this.productStatus = item.code
  168. this.getProductList()
  169. }
  170. },
  171. //是否管理商品
  172. manage() {
  173. this.isManage = !this.isManage
  174. this.isAll = true
  175. this.allSelect()
  176. },
  177. // 跳转至搜索页面
  178. goSearch() {
  179. uni.navigateTo({
  180. url: '/pages/product/search'
  181. })
  182. },
  183. //跳转至详情
  184. goDetails(item) {
  185. uni.navigateTo({
  186. url: '/pages/product/details?productId=' + item.productId
  187. })
  188. },
  189. //跳转至创建商品
  190. creatProduct() {
  191. uni.navigateTo({
  192. url: '/pages/product/creatProduct'
  193. })
  194. },
  195. //编辑
  196. edit(item) {
  197. uni.navigateTo({
  198. url: '/pages/product/creatProduct?productId=' + item.productId
  199. })
  200. },
  201. select(item) {
  202. item.select = !item.select
  203. this.productHandleList.push(item.productId)
  204. },
  205. //批量下架
  206. deletes() {
  207. let shelves = []
  208. this.productHandleList.forEach(item => {
  209. shelves.push({
  210. productId: item.productId,
  211. productStatus: 0
  212. })
  213. })
  214. let that = this
  215. uni.showModal({
  216. title: '确定下架商品?',
  217. success: function(res) {
  218. if (res.confirm) {
  219. that.$http.post("/app/product/shelves", shelves)
  220. .then(res => {
  221. if (res.data.code == 200) {
  222. console.log(res)
  223. uni.showToast({
  224. title: '下架成功',
  225. duration: 2000,
  226. icon: 'none'
  227. });
  228. that.getProductList()
  229. that.isManage = false
  230. that.isAll = false
  231. }
  232. })
  233. } else if (res.cancel) {
  234. console.log('用户点击取消');
  235. that.isAll = false
  236. that.allSelect()
  237. }
  238. }
  239. });
  240. },
  241. //批量删除
  242. remove() {
  243. this.productList.forEach((item => {
  244. this.productHandleList.push(item.productId)
  245. }))
  246. let ids = this.productHandleList.join(',')
  247. console.log(ids)
  248. let that = this
  249. uni.showModal({
  250. title: '确定删除商品?',
  251. success: function(res) {
  252. if (res.confirm) {
  253. that.$http.get("/app/product/deleteBatch?ids=" + ids, )
  254. .then(res => {
  255. if (res.data.code == 200) {
  256. console.log(res)
  257. uni.showToast({
  258. title: '删除成功',
  259. duration: 2000,
  260. icon: 'none'
  261. });
  262. that.getProductList()
  263. that.isManage = false
  264. that.isAll = false
  265. }
  266. })
  267. } else if (res.cancel) {
  268. console.log('用户点击取消');
  269. }
  270. }
  271. });
  272. },
  273. //全选
  274. allSelect() {
  275. if (this.isAll) {
  276. this.isAll = false
  277. this.productList.forEach(item => {
  278. item.select = false
  279. })
  280. } else {
  281. this.isAll = true
  282. this.productList.forEach(item => {
  283. item.select = true
  284. })
  285. }
  286. },
  287. getProductList() {
  288. this.$http.get("/app/product/list?merchantId=" + this.merchantId + "&productStatus=" + this.productStatus +
  289. '&productName=' + this.productName, )
  290. .then(res => {
  291. if (res.data.code == 200) {
  292. res.data.result.records.forEach((item) => {
  293. item.select = false;
  294. })
  295. this.productList = res.data.result.records
  296. console.log(this.productList)
  297. }
  298. })
  299. },
  300. delist(item) {
  301. console.log(item)
  302. let shelves = []
  303. shelves.push({
  304. productId: item.productId,
  305. productStatus: 0
  306. })
  307. let that = this
  308. uni.showModal({
  309. title: '确定下架商品',
  310. success: function(res) {
  311. if (res.confirm) {
  312. that.$http.post("/app/product/shelves", shelves)
  313. .then(res => {
  314. if (res.data.code == 200) {
  315. uni.showToast({
  316. title: '下架成功',
  317. duration: 2000,
  318. icon: 'none'
  319. });
  320. that.getProductList()
  321. }
  322. })
  323. } else if (res.cancel) {
  324. console.log('用户点击取消');
  325. }
  326. }
  327. });
  328. },
  329. //上架
  330. sell(item) {
  331. console.log(item)
  332. let shelves = []
  333. shelves.push({
  334. productId: item.productId,
  335. productStatus: 1
  336. })
  337. let that = this
  338. uni.showModal({
  339. title: '确定上架商品?',
  340. success: function(res) {
  341. if (res.confirm) {
  342. that.$http.post("/app/product/shelves", shelves)
  343. .then(res => {
  344. if (res.data.code == 200) {
  345. uni.showToast({
  346. title: '上架成功',
  347. duration: 2000,
  348. icon: 'none'
  349. });
  350. that.getProductList()
  351. }
  352. })
  353. } else if (res.cancel) {
  354. console.log('用户点击取消');
  355. }
  356. }
  357. });
  358. },
  359. getStatus() {
  360. this.$http.get("/app/product/statusCount?merchantId=" + this.merchantId, ).then(res => {
  361. if (res.data.code == 200) {
  362. this.typeList = res.data.result
  363. }
  364. })
  365. }
  366. },
  367. mounted() {
  368. this.getProductList()
  369. this.getStatus()
  370. },
  371. onShow() {
  372. let that = this
  373. uni.getStorage({
  374. key: 'login_user_info',
  375. success: function(res) {
  376. that.merchantId = res.data.id
  377. }
  378. })
  379. }
  380. }
  381. </script>
  382. <style lang="scss" scoped>
  383. .product {
  384. width: 100%;
  385. height: 100vh;
  386. display: flex;
  387. flex-direction: column;
  388. justify-content: space-between;
  389. background: #F7F8FC;
  390. .top {
  391. width: 100%;
  392. height: var(--status-bar-height);
  393. background: linear-gradient(87deg, #FFFFFF 0%, #A3CDFF 100%), linear-gradient(360deg, #FFFFFF 0%, rgba(255, 255, 255, 0) 100%);
  394. }
  395. .head {
  396. width: 100%;
  397. background: #ffffff;
  398. .handle {
  399. height: 112rpx;
  400. display: flex;
  401. justify-content: space-between;
  402. align-items: center;
  403. padding: 0px 24rpx;
  404. position: relative;
  405. background: linear-gradient(87deg, #FFFFFF 0%, #A3CDFF 100%), linear-gradient(360deg, #FFFFFF 0%, rgba(255, 255, 255, 0) 100%);
  406. .head_left {
  407. font-size: 40rpx;
  408. }
  409. .center {
  410. position: absolute;
  411. left: 50%;
  412. top: 50%;
  413. transform: translate(-50%, -50%);
  414. font-size: 36rpx;
  415. font-weight: 600;
  416. }
  417. .head_right {
  418. display: flex;
  419. justify-content: space-between;
  420. align-items: center;
  421. span {
  422. width: 40rpx;
  423. height: 40rpx;
  424. display: flex;
  425. justify-content: center;
  426. align-items: center;
  427. }
  428. .manage {
  429. // width: 150rpx;
  430. margin-left: 28rpx;
  431. }
  432. }
  433. }
  434. .search {
  435. width: 93%;
  436. height: 56rpx;
  437. background: #F7F8FC;
  438. border-radius: 12rpx;
  439. display: flex;
  440. align-items: center;
  441. justify-content: space-between;
  442. margin: 16rpx auto;
  443. font-size: 26rpx;
  444. padding: 13rpx 20rpx;
  445. span {
  446. margin-right: 15rpx;
  447. }
  448. input {
  449. flex: 1;
  450. font-size: 26rpx;
  451. }
  452. .search_btn {
  453. width: 72rpx;
  454. color: #333333;
  455. display: flex;
  456. align-items: center;
  457. justify-content: space-between;
  458. span {
  459. display: block;
  460. width: 1px;
  461. height: 26rpx;
  462. background-color: #eeeeee;
  463. }
  464. }
  465. }
  466. .type {
  467. display: flex;
  468. justify-content: space-between;
  469. background-color: #fff;
  470. padding: 8px 24rpx 16rpx;
  471. .type_item {
  472. height: 54rpx;
  473. display: flex;
  474. justify-content: center;
  475. align-items: center;
  476. font-size: 26rpx;
  477. color: #888888;
  478. position: relative;
  479. padding: 8rpx 12rpx;
  480. background: #F2F3F5;
  481. border-radius: 8rpx;
  482. }
  483. .active {
  484. color: #2D88F4;
  485. background: #ECF5FF;
  486. }
  487. }
  488. }
  489. .list {
  490. width: 100%;
  491. flex: 1;
  492. // padding: 0px 20rpx;
  493. overflow-y: auto;
  494. .product_item {
  495. width: 100%;
  496. background-color: #fff;
  497. border-radius: 20rpx;
  498. padding: 20rpx 40rpx;
  499. margin-top: 20rpx;
  500. .status {
  501. display: flex;
  502. align-items: center;
  503. .round {
  504. display: flex;
  505. align-items: center;
  506. color: #49A03F;
  507. }
  508. .round::before {
  509. content: "";
  510. display: inline-block;
  511. width: 9rpx;
  512. height: 9rpx;
  513. background: #49A03F;
  514. border-radius: 50%;
  515. margin-right: 8rpx;
  516. }
  517. .no {
  518. color: #666666;
  519. }
  520. .no::before {
  521. content: "";
  522. display: inline-block;
  523. width: 9rpx;
  524. height: 9rpx;
  525. background: #666666;
  526. border-radius: 50%;
  527. margin-right: 8rpx;
  528. }
  529. .audit {
  530. display: flex;
  531. align-items: center;
  532. color: #596ABB;
  533. }
  534. .audit::before {
  535. content: "";
  536. display: inline-block;
  537. width: 9rpx;
  538. height: 9rpx;
  539. background: #596ABB;
  540. border-radius: 50%;
  541. margin-right: 8rpx;
  542. }
  543. .reject {
  544. display: flex;
  545. align-items: center;
  546. color: #F55D65;
  547. }
  548. .reject::before {
  549. content: "";
  550. display: inline-block;
  551. width: 9rpx;
  552. height: 9rpx;
  553. background: #F55D65;
  554. border-radius: 50%;
  555. margin-right: 8rpx;
  556. }
  557. .line {
  558. display: block;
  559. width: 1rpx;
  560. height: 20rpx;
  561. background: #d9d9d9;
  562. margin: 0 12rpx;
  563. }
  564. }
  565. .details {
  566. width: 100%;
  567. height: auto;
  568. min-height: 132rpx;
  569. height: 132rpx;
  570. display: flex;
  571. align-items: center;
  572. margin-top: 20rpx;
  573. .img {
  574. margin-right: 16rpx;
  575. border-radius: 12rpx;
  576. overflow: hidden;
  577. image {
  578. width: 132rpx;
  579. height: 132rpx;
  580. }
  581. }
  582. .data {
  583. flex: 1;
  584. height: 100%;
  585. display: flex;
  586. flex-direction: column;
  587. justify-content: space-between;
  588. font-weight: 600;
  589. font-style: 28rpx;
  590. .repertory {
  591. font-size: 24rpx;
  592. display: flex;
  593. align-items: center;
  594. color: #666;
  595. font-weight: 400;
  596. span {
  597. display: block;
  598. width: 1rpx;
  599. height: 20rpx;
  600. background: #d9d9d9;
  601. margin: 0 12rpx;
  602. }
  603. }
  604. .price {
  605. display: flex;
  606. align-items: center;
  607. font-size: 30rpx;
  608. font-weight: 600;
  609. span {
  610. font-size: 26rpx;
  611. margin-left: 20rpx;
  612. font-weight: 400;
  613. }
  614. }
  615. }
  616. .tag {
  617. width: 40rpx;
  618. height: 40rpx;
  619. display: flex;
  620. flex-direction: column;
  621. align-items: center;
  622. image {
  623. width: 40rpx;
  624. height: 40rpx;
  625. }
  626. }
  627. }
  628. .btn_box {
  629. width: 100%;
  630. display: flex;
  631. justify-content: flex-end;
  632. align-items: center;
  633. margin-top: 20rpx;
  634. .delist {
  635. width: 100rpx;
  636. height: 50rpx;
  637. border-radius: 8rpx;
  638. border: 1px solid #CCCCCC;
  639. display: flex;
  640. justify-content: center;
  641. align-items: center;
  642. font-size: 26rpx;
  643. color: #666666;
  644. }
  645. .edit {
  646. margin-left: 20rpx;
  647. background: rgba(68, 154, 255, 0.05);
  648. border: 1px solid #449AFF;
  649. color: #449AFF;
  650. }
  651. }
  652. }
  653. }
  654. .creat {
  655. width: 100%;
  656. height: 100rpx;
  657. background-color: #fff;
  658. display: flex;
  659. justify-content: center;
  660. align-items: center;
  661. .btn {
  662. width: 672rpx;
  663. height: 76rpx;
  664. display: flex;
  665. justify-content: center;
  666. align-items: center;
  667. background: linear-gradient(90deg, #77B6FF 0%, #449AFF 100%);
  668. border-radius: 75rpx;
  669. font-size: 28rpx;
  670. color: #FFFFFF;
  671. image {
  672. width: 40rpx;
  673. height: 40rpx;
  674. margin-right: 10rpx;
  675. }
  676. }
  677. .operate {
  678. width: 100%;
  679. display: flex;
  680. // justify-content: space-between;
  681. align-items: center;
  682. padding: 0px 20rpx;
  683. .delete {
  684. width: 205rpx;
  685. height: 76rpx;
  686. background: linear-gradient(90deg, #77B6FF 0%, #449AFF 100%);
  687. border-radius: 49rpx;
  688. font-size: 28rpx;
  689. color: #FFFFFF;
  690. display: flex;
  691. justify-content: center;
  692. align-items: center;
  693. margin-right: 24rpx;
  694. margin-left: 140rpx;
  695. }
  696. .delist {
  697. margin-left: 0rpx;
  698. background: linear-gradient(90deg, #FFA05B 0%, #FF7918 100%);
  699. }
  700. .all {
  701. width: 25%;
  702. // height: 60rpx;
  703. // border: 1px solid #999;
  704. display: flex;
  705. justify-content: center;
  706. align-items: center;
  707. image {
  708. width: 40rpx;
  709. height: 40rpx;
  710. margin-right: 10rpx;
  711. }
  712. }
  713. }
  714. }
  715. .popup {
  716. width: 100vw;
  717. height: 100vh;
  718. position: fixed;
  719. top: 0;
  720. left: 0;
  721. background: rgba(0, 0, 0, 0.4);
  722. display: flex;
  723. align-items: center;
  724. justify-content: center;
  725. .content {
  726. width: 570rpx;
  727. background: #FFFFFF;
  728. border-radius: 16rpx;
  729. padding: 0px 24rpx;
  730. padding-bottom: 16rpx;
  731. .title {
  732. width: 100%;
  733. height: 86rpx;
  734. font-size: 32rpx;
  735. color: #333333;
  736. font-weight: 600;
  737. border-bottom: 1px solid #EEEEEE;
  738. display: flex;
  739. align-items: center;
  740. justify-content: center;
  741. }
  742. .center {
  743. font-size: 30rpx;
  744. color: #333333;
  745. line-height: 35rpx;
  746. display: flex;
  747. flex-direction: column;
  748. align-items: center;
  749. justify-content: center;
  750. padding-top: 28rpx;
  751. border-bottom: 1px solid #EEEEEE;
  752. padding-bottom: 40rpx;
  753. margin-bottom: 16rpx;
  754. .error {
  755. text-align: center;
  756. }
  757. image {
  758. width: 100rpx;
  759. height: 100rpx;
  760. margin-bottom: 10rpx;
  761. }
  762. }
  763. .sub {
  764. width: 320rpx;
  765. height: 68rpx;
  766. border-radius: 66rpx;
  767. font-size: 28rpx;
  768. color: #FFFFFF;
  769. display: flex;
  770. align-items: center;
  771. justify-content: center;
  772. margin: 0rpx auto;
  773. .button {
  774. width: 320rpx;
  775. height: 68rpx;
  776. background: #449AFF;
  777. border-radius: 66rpx;
  778. display: flex;
  779. align-items: center;
  780. justify-content: center;
  781. }
  782. }
  783. .start {
  784. background: #53CC48;
  785. }
  786. .rest {
  787. background: #FF8024;
  788. }
  789. }
  790. }
  791. }
  792. </style>