com-attr-group.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. <?php
  2. use common\helpers\ComponentHelper;
  3. ComponentHelper::loadComponentView('com-specs-select', __DIR__);
  4. ComponentHelper::loadComponentView('com-specs-values-select', __DIR__);
  5. ?>
  6. <style>
  7. .com-attr-group {
  8. border: 1px solid #EBEEF5;
  9. padding: 10px;
  10. }
  11. .com-attr-group .bg {
  12. height: 44px;
  13. padding: 0 10px;
  14. background: #f8f8f8;
  15. }
  16. .com-attr-group .del-img {
  17. height: 20px;
  18. width: 20px;
  19. cursor: pointer;
  20. }
  21. .com-attr-group .img-box {
  22. position: relative;
  23. height: 100px;
  24. width: 100px;
  25. margin-top: 8px;
  26. border: 1px solid #EBEEF5;
  27. }
  28. .com-attr-group .attr-jt {
  29. background: #ffffff;
  30. width: 6px;
  31. height: 6px;
  32. border-top: 1px solid rgb(235, 238, 245);
  33. border-right: 1px solid #EBEEF5;
  34. transform: rotate(-45deg);
  35. -o-transform: rotate(-45deg);
  36. -webkit-transform: rotate(-45deg);
  37. -moz-transform: rotate(-45deg);
  38. -ms-transform: rotate(-45deg);
  39. position: absolute;
  40. top: -5px;
  41. }
  42. .com-attr-group .close {
  43. position: absolute;
  44. top: -4px;
  45. right: -4px;
  46. font-size: 16px;
  47. cursor: pointer;
  48. }
  49. .com-attr-group .attr-list {
  50. display: inline-block;
  51. margin-right: 10px;
  52. /* margin-bottom: 10px; */
  53. position: relative;
  54. cursor: move;
  55. }
  56. </style>
  57. <template id="com-attr-group">
  58. <div class="com-attr-group">
  59. <div v-for="(group, i) in value" :key="i" style="margin-bottom: 16px">
  60. <div flex="dir:left cross:center" class="bg">
  61. <span>规格名:</span>
  62. <el-input type="text" v-model.trim="group.attr_group_name" size="mini" @input="makeAttrGroup"
  63. style="width:94px;margin:0 16px"></el-input>
  64. <!-- 自定义规格选择 -->
  65. <com-specs-select :load-more-loding="loadMoreLoding" :specs-list="specsList" :index="i" @load-more="loadMore" :group="group" @use-specs="useSpecs"></com-specs-select>
  66. <el-checkbox v-if="i === 0" v-model="attrPic">规格图片</el-checkbox>
  67. <div @click="deleteAttrGroup(i)" style="margin-left: auto;line-height: 1">
  68. <el-image class="del-img" src="resources/img/mall/order/del.png"></el-image>
  69. </div>
  70. </div>
  71. <div flex="dir:left" style="padding:0 10px;margin-top: 16px">
  72. <div class="box-grow-0">规格值:</div>
  73. <draggable :options="{draggable:'.attr-list'}" @end="makeAttrGroup"
  74. flex="dir:left" style="flex-wrap: wrap" v-model="group.attr_list">
  75. <div class="attr-list" v-for="(attr, j) in group.attr_list" :key="j">
  76. <el-input style="width:152px" size="mini" type="text" @input="makeAttrGroup"
  77. v-model.trim="attr.attr_name"></el-input>
  78. <i class="el-icon-error close" @click="deleteAttr(i,j)"></i>
  79. <div flex="cross:center main:center" class="img-box" v-if="i===0 && attrPic">
  80. <div class="attr-jt"></div>
  81. <div v-if="attr.pic_url" @mouseenter="attrPicEnter(j)">
  82. <el-image :src="attr.pic_url" style="height:88px;width:88px"></el-image>
  83. </div>
  84. <com-attachment v-else v-model="attr.pic_url" :multiple="false" :max="1" @selected="selectImg">
  85. <el-tooltip class="item" effect="dark" content="建议尺寸:750 * 750" placement="top">
  86. <el-button type="text" @click="uploadId(i, j)">+添加图片</el-button>
  87. </el-tooltip>
  88. </com-attachment>
  89. <i v-if="attrPicStatus === j && attr.pic_url" class="el-icon-error close"
  90. @click="attr.pic_url = ''"></i>
  91. <div v-if="attrPicStatus === j && attr.pic_url" style="position: absolute">
  92. <com-attachment v-model="attr.pic_url" :multiple="false" :max="1" @selected="selectImg">
  93. <el-button type="primary" @click="uploadId(i, j)">替换</el-button>
  94. </com-attachment>
  95. </div>
  96. </div>
  97. </div>
  98. <div slot="footer" flex="center">
  99. <!-- 使用预设规格值 -->
  100. <com-specs-values-select :specs="getUseSpecs(i)" :index="i" @use-specs-value="useSpecsValue"></com-specs-values-select>
  101. <el-button type="text" @click="addAttr(i)">添加规格值</el-button>
  102. </div>
  103. </draggable>
  104. </div>
  105. <div v-if="i === 0" style="margin-left: 65px;color:#c9c9c9">
  106. <p class="tips-text">
  107. 仅支持为第一组规格设置规格图片,买家选择不同规格会看到对应规格图片,建议尺寸:80 * 80像素
  108. </p>
  109. </div>
  110. </div>
  111. <div v-if="isAddAttrGroups" flex="dir:left cross:center" class="bg">
  112. <el-button @click="addAttrGroup">添加规格项目</el-button>
  113. <span style="padding-left: 14px;color:#c9c9c9">注:规格名最多添加5个</span>
  114. </div>
  115. </div>
  116. </template>
  117. <script>
  118. Vue.component('com-attr-group', {
  119. template: '#com-attr-group',
  120. props: {
  121. value: {
  122. type: Array,
  123. default: function () {
  124. return [];
  125. }
  126. }
  127. },
  128. data() {
  129. return {
  130. attrGroupMaxCount: 5, //可添加最大规格组
  131. isAddAttrGroups: true, //添加规格组按钮是否显示
  132. attrPic: true, //规格图片
  133. attrPicStatus: -1, //move
  134. specsPage: 1,
  135. specsLimit: 10,
  136. specsList: [],
  137. pageCount: 0,
  138. loadMoreLoding: false,
  139. specs: {},
  140. ids: {},
  141. };
  142. },
  143. watch: {
  144. 'attrPic'(newVal, oldVal) {
  145. if (!newVal) {
  146. this.value[0]['attr_list'].forEach((v) => {
  147. v.pic_url = '';
  148. })
  149. }
  150. },
  151. },
  152. created: function() {
  153. this.getSpecs()
  154. },
  155. methods: {
  156. makeAttrGroup() {
  157. this.$emit('select', this.value);
  158. },
  159. attrPicEnter(value) {
  160. if (this.attrPicStatus == value) {
  161. return;
  162. }
  163. this.attrPicStatus = value;
  164. },
  165. // 添加规格组
  166. addAttrGroup() {
  167. let attrGroundId = 0;
  168. if(this.value.length>0){
  169. attrGroundId = this.value[this.value.length - 1].attr_group_id;
  170. }
  171. this.value.push({
  172. attr_group_id: attrGroundId + 1,
  173. attr_group_name: '',
  174. attr_list: [],
  175. });
  176. // 限制添加的规格组
  177. if (this.value.length === this.attrGroupMaxCount) {
  178. this.isAddAttrGroups = false;
  179. }
  180. },
  181. // 删除规格组
  182. deleteAttrGroup(index) {
  183. this.value.splice(index, 1);
  184. if (this.value.length < this.attrGroupMaxCount) {
  185. this.isAddAttrGroups = true;
  186. }
  187. this.makeAttrGroup();
  188. },
  189. // 删除规格
  190. deleteAttr(i, j) {
  191. this.value[i].attr_list.splice(j, 1);
  192. this.makeAttrGroup();
  193. },
  194. // 添加规格
  195. addAttr(i) {
  196. this.value[i].attr_list.push({
  197. attr_id: this.getLastAttrId() + 1,
  198. attr_name: '',
  199. pic_url: '',
  200. });
  201. this.makeAttrGroup();
  202. },
  203. // 获取最后一个规格ID
  204. getLastAttrId() {
  205. let id = 1;
  206. this.value.forEach((attrGroupItem, attrGroupIndex) => {
  207. attrGroupItem.attr_list.forEach((v) => {
  208. id = (v.attr_id > id?v.attr_id:id);
  209. // console.info(v.attr_id,"id",id);
  210. });
  211. });
  212. return id;
  213. },
  214. getSpecs() {
  215. request({
  216. params: {
  217. r: 'mall/specs/index',
  218. page: this.specsPage,
  219. limit: this.specsLimit
  220. },
  221. method: 'get',
  222. }).then(e => {
  223. if (e.data.code === 0) {
  224. this.specsList = [
  225. ...this.specsList,
  226. ...e.data.data.list
  227. ]
  228. this.pageCount = e.data.data.page_count
  229. this.loadMoreLoding = false
  230. }
  231. })
  232. },
  233. /**
  234. * 加载更多
  235. */
  236. loadMore() {
  237. if (this.loadMoreLoding) {
  238. return
  239. }
  240. if (this.specsPage >= this.pageCount) {
  241. this.$message.warning('暂无更多')
  242. return
  243. }
  244. this.loadMoreLoding = true
  245. this.specsPage++
  246. this.getSpecs()
  247. },
  248. getUseSpecs(i) {
  249. return this.specs[i]
  250. },
  251. /**
  252. * 使用规格
  253. */
  254. useSpecs(item, group, i) {
  255. this.specs[i] = item
  256. group.attr_group_name = item.name
  257. },
  258. useSpecsValue(v, i) {
  259. let index = this.value[i].attr_list.findIndex(function (item) {
  260. return item.attr_name == v
  261. })
  262. if (index == -1) {
  263. this.value[i].attr_list.push({
  264. attr_id: this.getLastAttrId() + 1,
  265. attr_name: v,
  266. pic_url: '',
  267. });
  268. this.makeAttrGroup();
  269. }
  270. },
  271. /**
  272. * 选中图片
  273. */
  274. selectImg(e) {
  275. let i = this.ids.i
  276. let j = this.ids.j
  277. this.value[i].attr_list[j].pic_url = e[0].url
  278. this.makeAttrGroup()
  279. },
  280. uploadId(i, j) {
  281. this.ids.i = i
  282. this.ids.j = j
  283. },
  284. }
  285. });
  286. </script>