com-attr-group.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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. methods: {
  153. makeAttrGroup() {
  154. this.$emit('select', this.value);
  155. },
  156. attrPicEnter(value) {
  157. if (this.attrPicStatus == value) {
  158. return;
  159. }
  160. this.attrPicStatus = value;
  161. },
  162. // 添加规格组
  163. addAttrGroup() {
  164. let attrGroundId = 0;
  165. if(this.value.length>0){
  166. attrGroundId = this.value[this.value.length - 1].attr_group_id;
  167. }
  168. this.value.push({
  169. attr_group_id: attrGroundId + 1,
  170. attr_group_name: '',
  171. attr_list: [],
  172. });
  173. // 限制添加的规格组
  174. if (this.value.length === this.attrGroupMaxCount) {
  175. this.isAddAttrGroups = false;
  176. }
  177. },
  178. // 删除规格组
  179. deleteAttrGroup(index) {
  180. this.value.splice(index, 1);
  181. if (this.value.length < this.attrGroupMaxCount) {
  182. this.isAddAttrGroups = true;
  183. }
  184. this.makeAttrGroup();
  185. },
  186. // 删除规格
  187. deleteAttr(i, j) {
  188. this.value[i].attr_list.splice(j, 1);
  189. this.makeAttrGroup();
  190. },
  191. // 添加规格
  192. addAttr(i) {
  193. this.value[i].attr_list.push({
  194. attr_id: this.getLastAttrId() + 1,
  195. attr_name: '',
  196. pic_url: '',
  197. });
  198. this.makeAttrGroup();
  199. },
  200. // 获取最后一个规格ID
  201. getLastAttrId() {
  202. let id = 1;
  203. this.value.forEach((attrGroupItem, attrGroupIndex) => {
  204. attrGroupItem.attr_list.forEach((v) => {
  205. id = (v.attr_id > id?v.attr_id:id);
  206. // console.info(v.attr_id,"id",id);
  207. });
  208. });
  209. return id;
  210. },
  211. getSpecs() {
  212. request({
  213. params: {
  214. r: 'store/specs/index',
  215. page: this.specsPage,
  216. limit: this.specsLimit
  217. },
  218. method: 'get',
  219. }).then(e => {
  220. if (e.data.code === 0) {
  221. this.specsList = [
  222. ...this.specsList,
  223. ...e.data.data.list
  224. ]
  225. this.pageCount = e.data.data.page_count
  226. this.loadMoreLoding = false
  227. }
  228. })
  229. },
  230. /**
  231. * 加载更多
  232. */
  233. loadMore() {
  234. if (this.loadMoreLoding) {
  235. return
  236. }
  237. if (this.specsPage >= this.pageCount) {
  238. this.$message.warning('暂无更多')
  239. return
  240. }
  241. this.loadMoreLoding = true
  242. this.specsPage++
  243. this.getSpecs()
  244. },
  245. getUseSpecs(i) {
  246. return this.specs[i]
  247. },
  248. /**
  249. * 使用规格
  250. */
  251. useSpecs(item, group, i) {
  252. this.specs[i] = item
  253. group.attr_group_name = item.name
  254. },
  255. useSpecsValue(v, i) {
  256. let index = this.value[i].attr_list.findIndex(function (item) {
  257. return item.attr_name == v
  258. })
  259. if (index == -1) {
  260. this.value[i].attr_list.push({
  261. attr_id: this.getLastAttrId() + 1,
  262. attr_name: v,
  263. pic_url: '',
  264. });
  265. this.makeAttrGroup();
  266. }
  267. },
  268. /**
  269. * 选中图片
  270. */
  271. selectImg(e) {
  272. let i = this.ids.i
  273. let j = this.ids.j
  274. this.value[i].attr_list[j].pic_url = e[0].url
  275. this.makeAttrGroup()
  276. },
  277. uploadId(i, j) {
  278. this.ids.i = i
  279. this.ids.j = j
  280. },
  281. }
  282. });
  283. </script>