Index.vue 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. <template><page-meta :root-font-size="fontSize+'px'"></page-meta>
  2. <seller-base :show="false">
  3. <view class="div container seller-spec">
  4. <view class="div common-header-wrap">
  5. <view :style="'height:'+navHeight+'px'"></view>
  6. <view class="common-header-holder"></view>
  7. <view class="common-header-fixed">
  8. <title-header />
  9. <uni-nav-bar title="商品规格" class="common-header" left-icon="back" @clickLeft="goBack()">
  10. </uni-nav-bar>
  11. </view>
  12. </view>
  13. <view class="div main-content">
  14. <view class="div" @click="showPopup('classVisible')">
  15. <flex-line class="menu-item" :is-link="true" :show-border="true"><text class="span line-name">商品分类</text><text class="span" slot="right">{{goods_class.gc_name}}</text></flex-line>
  16. </view>
  17. <view class="div" v-if="spec_list">
  18. <view class="div" v-for="(val,k) in spec_list" :key="k">
  19. <flex-line class="mt-5" :show-border="true"><text class="span line-name">{{val.sp_name}}</text><view class="div" slot="right"><view class="div common-btn ds-button-small default" @click="addSpec(k)">添加规格值</view></view></flex-line>
  20. <view class="div row-line" v-for="(item,index) in val.value" :key="index">
  21. <input class="input" placeholder="规格值" v-model="item.spvalue_name" />
  22. <text class="span del iconfont" @click="delSpec(k,index)">&#xe669;</text>
  23. </view>
  24. </view>
  25. </view>
  26. <view class="div pt-10 pb-10"><view class="div common-btn ds-button-large" @click="submit">保存</view></view>
  27. </view>
  28. <view class="div">
  29. <uni-popup background-color="#fff" ref="classVisible" type="bottom">
  30. <view>
  31. <view class="div toolbar">
  32. <text class="button toolbar-item cancel-item" @click="cancelClass">取消</text>
  33. <view class="div picker-header">选择分类</view>
  34. <text class="button toolbar-item confirm-item" @click="confirmClass">确定</text>
  35. </view>
  36. </view>
  37. <picker-view class="popup-content" indicator-style="height:80rpx" @change="onClassChange" :value="gcPicker">
  38. <picker-view-column v-for="(item,index) in buildItems" :key="index">
  39. <view class="popup-item-wrapper" v-for="(v,i) in item.values" :key="i"><text class="popup-item">{{v.value}}</text></view>
  40. </picker-view-column>
  41. </picker-view>
  42. </uni-popup>
  43. </view>
  44. </view>
  45. <uni-popup background-color="#fff" ref="confirm" type="dialog">
  46. <uni-popup-dialog :mode="dialog.mode" :title="dialog.title" :content="dialog.content" :placeholder="dialog.content" @confirm="confirmDialog" @close="closeDialog"></uni-popup-dialog>
  47. </uni-popup>
  48. </seller-base>
  49. </template>
  50. <script>
  51. import {getFontSize} from '@/util/common'
  52. import TitleHeader from '../../TitleHeader'
  53. import SellerBase from '../SellerBase'
  54. import { mapState, mapActions } from 'vuex'
  55. import { getCommonData, getGoodsClass, goodsSpecSave } from '../../../api/sellerGoods'
  56. import flexLine from '../../flexLine'
  57. export default {
  58. data(){
  59. return {
  60. navHeight: 0,
  61. gcPicker:[0,0,0],
  62. dialog:{},
  63. goods_class: {},
  64. store_bind_class: false,
  65. spec_list: false
  66. }
  67. },
  68. components:{TitleHeader,SellerBase,flexLine,},
  69. computed:{
  70. fontSize(){
  71. return getFontSize()
  72. },
  73. ...mapState({
  74. items: state => state.goodsclass.items
  75. }),
  76. buildItems: function () {
  77. if (!this.items || !this.store_bind_class || !this.items[0]) {
  78. return []
  79. }
  80. let items = new Array()
  81. if (this.store_bind_class.bind_all) {
  82. this.getDefaultItems(this.items, items)
  83. } else {
  84. this.getDefaultItems(this.store_bind_class.goods_class, items)
  85. }
  86. return items
  87. }
  88. },
  89. created () {
  90. getGoodsClass('Sellergoods').then(res => {
  91. this.store_bind_class = res.result
  92. }).catch(error => {
  93. uni.showToast({icon:'none',title: error.message})
  94. })
  95. this.fetchGoodsclassList()
  96. },
  97. mounted(){
  98. // #ifdef MP-WEIXIN
  99. this.navHeight = uni.getMenuButtonBoundingClientRect().height
  100. // #endif
  101. },
  102. methods:{
  103. closeDialog(){
  104. },
  105. confirmDialog(value){
  106. this.spec_list[this.dialog.data.key]['value'].splice(this.dialog.data.index, 1)
  107. },
  108. showPopup(id){
  109. this.$refs[id].open()
  110. },
  111. hidePopup(id){
  112. this.$refs[id].close()
  113. },
  114. goBack(){uni.navigateBack({delta:1})},
  115. ...mapActions({
  116. fetchGoodsclassList: 'fetchGoodsclassList'
  117. }),
  118. submit () {
  119. uni.showLoading({ title: '加载中' })
  120. goodsSpecSave({ spec_list: this.spec_list, gc_id: this.goods_class.gc_id }).then(res => {
  121. uni.hideLoading()
  122. uni.showToast({icon:'none',title: res.message})
  123. this.getSpec()
  124. }).catch(error => {
  125. uni.hideLoading()
  126. uni.showToast({icon:'none',title: error.message})
  127. })
  128. },
  129. delSpec (key, index) {
  130. if (this.spec_list[key]['value'][index]['spvalue_name']) {
  131. this.dialog={content:'确定要删除该规格值吗?',data:{key:key,index:index}}
  132. this.$refs.confirm.open()
  133. } else {
  134. this.spec_list[key]['value'].splice(index, 1)
  135. }
  136. },
  137. addSpec (index) {
  138. this.spec_list[index]['value'].push({})
  139. },
  140. getSpec () {
  141. getCommonData('Sellergoods', this.goods_class.gc_id).then(res => {
  142. var spec_list = res.result.spec_list
  143. this.spec_list = spec_list
  144. }).catch(error => {
  145. uni.showToast({icon:'none',title: error.message})
  146. })
  147. },
  148. getDefaultItems (_item, defaultItems) {
  149. defaultItems.push({
  150. flex: 1,
  151. values: _item,
  152. textAlign: 'center'
  153. })
  154. defaultItems.push({
  155. flex: 1,
  156. values: _item[0].children,
  157. textAlign: 'center'
  158. })
  159. defaultItems.push({
  160. flex: 1,
  161. values: (_item[0].children && _item[0].children.length) ? _item[0].children[0].children : [],
  162. textAlign: 'center'
  163. })
  164. },
  165. cancelClass () {
  166. this.hidePopup('classVisible')
  167. },
  168. confirmClass () {
  169. let values = []
  170. for(var i in this.gcPicker){
  171. values[i]=this.buildItems[i]['values'][this.gcPicker[i]]
  172. if(!values[i]){
  173. values[i]={
  174. id:0,
  175. value:''
  176. }
  177. }
  178. }
  179. var temp = values[2]
  180. if (!temp.id) {
  181. temp = values[1]
  182. }
  183. if (!temp.id) {
  184. temp = values[0]
  185. }
  186. this.goods_class.gc_name = temp.value
  187. this.goods_class.gc_id = temp.id
  188. this.cancelClass()
  189. this.getSpec()
  190. },
  191. onClassChange (e) {
  192. let value=e.detail.value
  193. let gcPicker=this.gcPicker
  194. for(var i in value){
  195. gcPicker[i]=value[i]
  196. i=parseInt(i)
  197. if(i<(value.length-1)){
  198. if(!this.buildItems[i]['values'].length || !this.buildItems[i]['values'][value[i]]['children'] || !this.buildItems[i]['values'][value[i]]['children'].length){
  199. this.buildItems[i+1]['values']=[]
  200. gcPicker[i+1]=0
  201. }else if(!this.buildItems[i+1]['values'].length || this.buildItems[i]['values'][value[i]]['children'][0]['id']!=this.buildItems[i+1]['values'][0]['id']){
  202. this.buildItems[i+1]['values']=this.buildItems[i]['values'][value[i]]['children']
  203. gcPicker[i+1]=0
  204. }
  205. }
  206. }
  207. this.gcPicker=gcPicker
  208. this.$forceUpdate()
  209. }
  210. }
  211. }
  212. </script>
  213. <style lang="scss">
  214. .seller-spec .mint-checklist-title{margin:0}
  215. </style>
  216. <style scoped lang="scss">
  217. .main-content{background: #fff;padding:0 $pageSpace}
  218. .row-line{
  219. display: flex;
  220. .content{flex:1}
  221. }
  222. .toolbar {
  223. height: 2rem;
  224. display: flex;
  225. flex-direction: row;
  226. justify-content: space-between;
  227. align-items: center;
  228. background-color: #f0f2f5;
  229. .toolbar-item {
  230. font-size:$fontSize;
  231. border: none;
  232. border-radius: 0;
  233. background-color: #f0f2f5;
  234. }
  235. .cancel-item {
  236. margin-left: 0.5rem;
  237. color: #4e545d;
  238. }
  239. .confirm-item {
  240. margin-right: 0.5rem;
  241. color: red;
  242. }
  243. .picker-header {
  244. color: #4e545d;
  245. line-height: 2rem;
  246. font-size:$h2;
  247. }
  248. }
  249. .row-line{background: #fff;padding:.3rem .5rem;align-items: center;
  250. .input{flex:1;padding:.3rem 0;border:0;}
  251. }
  252. .popup-content {
  253. padding: 0 40rpx;
  254. height: 300rpx;
  255. }
  256. .popup-item-wrapper{
  257. display: flex;
  258. justify-content: center;
  259. align-items: center;
  260. }
  261. .popup-item {
  262. font-size: 30rpx;
  263. line-height:80rpx;
  264. text-align: center;
  265. overflow: hidden;
  266. text-overflow: ellipsis;
  267. white-space: nowrap;
  268. }
  269. </style>