arrts.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  1. <template>
  2. <view class="content">
  3. <view class="showarrt-box" v-if="arrts.length != 0">
  4. <view class="showarrt-item flex" :key="index" v-for="(item,index) in arrts">
  5. <view class="show-name">
  6. {{item.value}}
  7. </view>
  8. <view class="show-info clamp" @click="open(item,index)">
  9. <text v-for='(ite,ind) in item.detail'>{{ite}} <text
  10. v-if="(ind+1) != item.detail.length">,</text></text>
  11. </view>
  12. </view>
  13. </view>
  14. <view class="btn-box flex">
  15. <view class="addarrt-btn " @click="open()">
  16. 添加新规格
  17. </view>
  18. <view class="shengchen" @click="scarrt()" v-if="arrts.length != 0">
  19. 立即生成
  20. </view>
  21. </view>
  22. <view class="batch" v-if="header.length != 0 && values.length !=0">
  23. <view class="batch-title">
  24. 批量设置
  25. </view>
  26. <view class="box-1">
  27. <view class="box-left">
  28. 商品规格图片
  29. <text class="imp">*</text>
  30. </view>
  31. <view class="box-image" @click="navCroper(400,400,'guige')">
  32. <image v-if="guige" :src="guige" mode=""></image>
  33. <image v-else src="../../../static/img/addP.png" mode=""></image>
  34. </view>
  35. </view>
  36. <view class="box-1">
  37. <view class="box-left">
  38. 商品售价
  39. <text class="imp">*</text>
  40. </view>
  41. <input type="number" placeholder="请填写商品售价" value="" class="list-input" v-model="price" />
  42. </view>
  43. <view class="box-1">
  44. <view class="box-left">
  45. 商品成本价
  46. <text class="imp">*</text>
  47. </view>
  48. <input type="number" placeholder="请填写商品成本价" value="" class="list-input" v-model="o_price" />
  49. </view>
  50. <view class="box-1">
  51. <view class="box-left">
  52. 商品原价
  53. <text class="imp">*</text>
  54. </view>
  55. <input type="number" placeholder="请填写商品原价" value="" class="list-input" v-model="y_price" />
  56. </view>
  57. <view class="box-1">
  58. <view class="box-left">
  59. 佣金计算值
  60. <text class="imp">*</text>
  61. </view>
  62. <input type="number" placeholder="请填写佣金计算值" value="" class="list-input" v-model="breakprice" />
  63. </view>
  64. <view class="box-1">
  65. <view class="box-left">
  66. 库存
  67. <text class="imp">*</text>
  68. </view>
  69. <input type="number" placeholder="请填写库存" value="" class="list-input" v-model="stock" />
  70. </view>
  71. <view class="batch-btn" @click="setup()">
  72. 批量设置
  73. </view>
  74. </view>
  75. <view class="batch" v-for="(item,index) in values">
  76. <view v-for="(itm,ind) in header">
  77. <view class="box-1" v-if="itm.title != '操作' && itm.title != '图片'">
  78. <view class="box-left">
  79. {{itm.title}}
  80. </view>
  81. <input type="text" v-if="itm.slot && itm.title == '产品编号'" :placeholder="'请填写'+itm.title" value=""
  82. class="list-input" v-model="item[itm.slot]" />
  83. <input type="number" v-if="itm.slot && itm.title != '产品编号'" :placeholder="'请填写'+itm.title" value=""
  84. class="list-input" v-model="item[itm.slot]" />
  85. <input type="text" v-if="itm.key" :placeholder="'请填写'+itm.title" value="" class="list-input"
  86. disabled="" v-model="item[itm.key]" />
  87. </view>
  88. <view class="box-1" v-if="itm.title == '图片'">
  89. <view class=" box-left">
  90. {{itm.title}}
  91. <text class="imp">*</text>
  92. </view>
  93. <view class="box-image" @click="navCroper(400,400,index)">
  94. <image v-if="item[itm.slot]" :src="item[itm.slot]" mode=""></image>
  95. <image v-else src="../../../static/img/addP.png" mode=""></image>
  96. </view>
  97. </view>
  98. </view>
  99. <view class="batch-btn" @click="del(index)">
  100. 删除
  101. </view>
  102. </view>
  103. <uni-popup ref="arrt" type="bottom">
  104. <view class="choose-main">
  105. <view class="choose-top flex">
  106. <view class="choose-font" @click="close()">
  107. 取消
  108. </view>
  109. <view class="choose-del" v-if="tebindex|| tebindex===0" @click="dearrt()">
  110. 删除
  111. </view>
  112. <view class="choose-qd" @click="qd()">
  113. 确定
  114. </view>
  115. </view>
  116. <scroll-view scroll-y="true" style="height: 600rpx;">
  117. <view class="addarrt-box">
  118. <view class="box-1">
  119. <view class="box-left">
  120. 规格
  121. <text class="imp">*</text>
  122. </view>
  123. <view class="list-input">
  124. <input v-if="isqd == 1" type="text" placeholder="请修改规格" value="" class="input"
  125. v-model="arrtname" @blur="jcarrtvalue" />
  126. <input v-if="isqd ==0" type="text" placeholder="请填写规格" value="" class="list-input"
  127. v-model="showarrtname" />
  128. <view class="delarrts" v-if="isqd ==0" @click="addarrtname()">
  129. 添加
  130. </view>
  131. </view>
  132. </view>
  133. <view class="box-1" v-for="(item,index) in addarrts">
  134. <view class="box-left">
  135. 修改规格值
  136. <text class="imp">*</text>
  137. </view>
  138. <view class="list-input">
  139. <input type="text" placeholder="请修改规格值" :value="item" class="input"
  140. v-model="addarrts[index]" @blur="jcarrtvalue" />
  141. <view class="delarrts" @click="delarrtvalue(index)">
  142. 删除
  143. </view>
  144. </view>
  145. </view>
  146. <view class="box-1" v-if="isqd == 1">
  147. <view class="box-left">
  148. 规格值
  149. <text class="imp">*</text>
  150. </view>
  151. <view class="list-input">
  152. <input type="text" class="" placeholder="请填写规格值" value="" v-model="addarrt" />
  153. <view class="delarrts" @click="addarrtvalue">
  154. 添加
  155. </view>
  156. </view>
  157. </view>
  158. </view>
  159. </scroll-view>
  160. </view>
  161. </uni-popup>
  162. </view>
  163. </template>
  164. <script>
  165. import {
  166. is_format_attr
  167. } from '@/api/upload.js'
  168. export default {
  169. props: {
  170. //分类选项
  171. baseURL: {
  172. type: String,
  173. default: ''
  174. },
  175. value: {
  176. type: Array,
  177. default: []
  178. },
  179. item: {
  180. type: Array,
  181. }
  182. },
  183. data() {
  184. return {
  185. values: this.value,
  186. items: this.item ? this.item : [],
  187. header: [], //规格头
  188. tebindex: '', //第几个规格
  189. arrts: [], //规格值
  190. showarrts: {
  191. value: '',
  192. detail: []
  193. }, //显示一条规格的东西
  194. isqd: 0, //是否添加完成规格0没有1开始修改
  195. showarrtname: '', //添加的规格
  196. arrtname: '', //添加的规格
  197. addarrts: [], //添加的规格值列表
  198. addarrt: '', //添加的规格值
  199. guige: '', //单规格图片
  200. price: '', //单规格售价
  201. o_price: '', //单规格成本价
  202. y_price: '', //单规格原价
  203. breakprice: '', //单规格佣金计算值
  204. stock: '', //单规格库存
  205. };
  206. },
  207. mounted() {
  208. console.log(this.values);
  209. if (this.items.length != 0) {
  210. this.arrts = this.items
  211. this.scarrt()
  212. }
  213. },
  214. methods: {
  215. open(opt, ind) {
  216. console.log(opt, ind, );
  217. if (opt) {
  218. this.arrtname = opt.value
  219. this.addarrts = opt.detail
  220. }
  221. if (ind != undefined) {
  222. this.tebindex = ind;
  223. console.log(this.tebindex);
  224. }
  225. this.$refs.arrt.open()
  226. },
  227. close() {
  228. this.isqd = 0
  229. this.showarrtname = ''
  230. this.tebindex = ''
  231. this.arrtname = '';
  232. this.addarrts = [];
  233. this.addarrt = '';
  234. this.$refs.arrt.close()
  235. },
  236. setup() {
  237. const obj = this
  238. this.value.forEach(e => {
  239. if (obj.guige) {
  240. e.pic = obj.guige
  241. }
  242. if (obj.price) {
  243. e.price = obj.price * 1
  244. }
  245. if (obj.o_price) {
  246. e.cost = obj.o_price * 1
  247. }
  248. if (obj.y_price) {
  249. e.ot_price = obj.y_price * 1
  250. }
  251. if (obj.breakprice) {
  252. e.brokerage_origin = obj.breakprice
  253. }
  254. if (obj.stock) {
  255. e.stock = obj.stock
  256. }
  257. })
  258. },
  259. addarrtname() {
  260. if (this.showarrtname == '') {
  261. return this.$api.msg("请填写规则")
  262. }
  263. this.isqd = 1
  264. this.arrtname = this.showarrtname
  265. this.showarrtname = ''
  266. },
  267. succ() {
  268. console.log(this.value, '111');
  269. this.$emit('getarrts', this.value, this.item);
  270. },
  271. addarrtvalue(e) {
  272. if (this.addarrt) {
  273. this.addarrts.push(this.addarrt)
  274. this.addarrt = ''
  275. }
  276. },
  277. delarrtvalue(ind) {
  278. console.log(ind, '123456');
  279. if (this.arrts.length == 1) {
  280. return this.$api.msg('请设置至少一个规则值')
  281. }
  282. this.addarrts.splice(ind, 1)
  283. },
  284. dearrt() {
  285. this.arrts.splice(this.tebindex, 1)
  286. this.close()
  287. },
  288. del(index) {
  289. if (this.value.length == 1) {
  290. return this.$api.msg('请设置至少一个规则')
  291. }
  292. this.value.splice(index, 1)
  293. },
  294. jcarrtvalue(e, type) {
  295. if (!e.detail.value) {
  296. return this.$api.msg('规格值不能为空')
  297. }
  298. },
  299. qd() {
  300. if (this.addarrts.length == 0) {
  301. this.close();
  302. return this.$api.msg('规格值不能为空')
  303. }
  304. if (typeof(this.tebindex) != 'string') {
  305. console.log(this.tebindex);
  306. this.arrts[this.tebindex].value = this.arrtname;
  307. this.arrts[this.tebindex].detail = this.addarrts;
  308. } else {
  309. let data = {
  310. value: '',
  311. detail: [],
  312. attrHidden: '',
  313. detailValue: ''
  314. };
  315. data.value = this.arrtname;
  316. data.detail = this.addarrts;
  317. this.arrts.push(data);
  318. }
  319. this.close()
  320. },
  321. upLoad(path) {
  322. // #ifdef H5
  323. console.log(path, 'h5');
  324. // #endif
  325. uni.showLoading({
  326. title: '图片上传中',
  327. mask: true
  328. });
  329. return new Promise((resolve, error) => {
  330. uni.uploadFile({
  331. url: this.baseURL + '/api/upload/image', //仅为示例,非真实的接口地址
  332. filePath: path,
  333. name: 'file',
  334. header: {
  335. "Authori-zation": 'Bearer ' + uni.getStorageSync('token')
  336. },
  337. success: (uploadFileRes) => {
  338. if ("string" === typeof uploadFileRes.data) {
  339. resolve(JSON.parse(uploadFileRes.data).data)
  340. } else {
  341. resolve(uploadFileRes.data.data)
  342. }
  343. },
  344. complete() {
  345. uni.hideLoading()
  346. }
  347. });
  348. })
  349. },
  350. navCroper(w, h, type) {
  351. let that = this;
  352. this.onImg().then((url) => {
  353. uni.navigateTo({
  354. url: `/pages/set/cropper?width=${w}&height=${h}`,
  355. events: {
  356. uploadSuccess(res) {
  357. that.upLoad(res).then((urldata) => {
  358. if (type == 'guige') {
  359. that.guige = urldata.url
  360. } else {
  361. that.value[type].pic = urldata.url
  362. }
  363. })
  364. }
  365. },
  366. success: function(res) {
  367. // 通过eventChannel向被打开页面传送数据
  368. res.eventChannel.emit('urlNext', {
  369. url
  370. })
  371. }
  372. })
  373. })
  374. },
  375. onImg(type) {
  376. const _this = this
  377. return new Promise((ok, erro) => {
  378. // 判断是否需要选择
  379. uni.showActionSheet({
  380. itemList: ['拍照', '选择一张照片'],
  381. success: function(res) {
  382. _this.chooseImage(res.tapIndex).then((url) => {
  383. ok(url)
  384. }).catch((res) => {
  385. erro(res)
  386. })
  387. },
  388. fail: function(res) {
  389. erro(res)
  390. console.log(res.errMsg);
  391. }
  392. });
  393. })
  394. },
  395. chooseImage: function(index) {
  396. const _this = this
  397. return new Promise((ok, error) => {
  398. // 从相册/相机选择
  399. // 如需直接开相机或直接选相册,请只使用一个选项
  400. const sourceType = index === 0 ? ['camera'] : ['album']
  401. uni.chooseImage({
  402. count: 1, //默认9
  403. sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
  404. sourceType: sourceType,
  405. success: function(res) {
  406. ok(res.tempFilePaths[0])
  407. },
  408. fail(e) {
  409. uni.showModal({
  410. title: '文件打开错误',
  411. content: '请设置授权文件存储权限',
  412. showCancel: false,
  413. });
  414. error(e)
  415. }
  416. });
  417. })
  418. },
  419. // 生成规格
  420. scarrt() {
  421. uni.showLoading({
  422. title: '生成中'
  423. })
  424. is_format_attr({
  425. attrs: this.arrts
  426. }).then(({
  427. data
  428. }) => {
  429. uni.hideLoading()
  430. this.items = data.attr
  431. this.header = data.header
  432. if (!this.values) {
  433. this.values = data.value
  434. }
  435. }).catch(err => {
  436. uni.hideLoading()
  437. })
  438. }
  439. }
  440. };
  441. </script>
  442. <style lang="scss">
  443. page,
  444. .content {
  445. min-height: 100%;
  446. height: auto;
  447. }
  448. .addarrt-box {
  449. padding: 20rpx;
  450. .btn {
  451. display: flex;
  452. justify-content: center;
  453. align-items: center;
  454. width: 200rpx;
  455. height: 54rpx;
  456. background: #000000;
  457. border-radius: 38rpx;
  458. font-size: 34rpx;
  459. font-family: PingFang SC;
  460. font-weight: 500;
  461. color: #ffffff;
  462. margin: 40rpx auto 20rpx;
  463. }
  464. }
  465. .box-1 {
  466. display: flex;
  467. justify-content: space-between;
  468. align-items: center;
  469. width: 100%;
  470. padding-top: 20rpx;
  471. .box-left {
  472. padding-left: 2rpx;
  473. width: 30%;
  474. text-align: left;
  475. color: #000000;
  476. .imp {
  477. color: #e63931;
  478. }
  479. }
  480. input {
  481. height: 66rpx;
  482. line-height: 66rpx;
  483. // height: 88rpx;
  484. }
  485. .list-input {
  486. color: #9598a3;
  487. height: 66rpx;
  488. padding-left: 24rpx;
  489. font-size: 28rpx;
  490. display: flex;
  491. justify-content: flex-end;
  492. align-items: center;
  493. width: 75%;
  494. flex: 1;
  495. text-align: right;
  496. padding-right: 24rpx;
  497. .input {
  498. color: #9598a3;
  499. width: 100%;
  500. .input-placeholder {
  501. height: 70rpx;
  502. color: #959595;
  503. }
  504. }
  505. .delarrts {
  506. margin-left: 20rpx;
  507. flex-shrink: 0;
  508. line-height: 1;
  509. padding: 10rpx 20rpx;
  510. background: #ffffff;
  511. border-radius: 10rpx;
  512. font-size: 24rpx;
  513. font-family: PingFang SC;
  514. font-weight: 500;
  515. color: #fd3b39;
  516. border: 1px solid #fd3b39;
  517. }
  518. }
  519. .box-image {
  520. height: 66rpx;
  521. width: 66rpx;
  522. image {
  523. width: 100%;
  524. height: 100%;
  525. }
  526. }
  527. }
  528. .showarrt-box {
  529. background: #ffffff;
  530. .showarrt-item {
  531. margin-top: 20rpx;
  532. height: 66rpx;
  533. .show-name {
  534. padding-left: 2rpx;
  535. width: 50%;
  536. text-align: left;
  537. color: #000000;
  538. }
  539. .show-info {
  540. width: 50%;
  541. font-size: 28rpx;
  542. color: #959595;
  543. text-align: right;
  544. padding-right: 24rpx;
  545. }
  546. }
  547. }
  548. .btn-box {
  549. background: #ffffff;
  550. padding: 20rpx 0;
  551. .addarrt-btn {
  552. color: #256fe7;
  553. }
  554. .shengchen {
  555. padding-left: 24rpx;
  556. background: #ffffff;
  557. padding: 20rpx 0;
  558. color: #e63931;
  559. }
  560. }
  561. .choose-main {
  562. background: #ffffff;
  563. }
  564. .choose-top {
  565. padding: 20rpx 40rpx 20rpx;
  566. font-size: 32rpx;
  567. .choose-font {
  568. color: #d4c7c2;
  569. }
  570. .choose-del {
  571. color: #256fe7;
  572. }
  573. .choose-qd {
  574. color: #e63931;
  575. }
  576. }
  577. .batch {
  578. border: 1px solid #000000;
  579. border-radius: 10rpx;
  580. margin-top: 20rpx;
  581. padding: 20rpx;
  582. background: #ffffff;
  583. .batch-title {
  584. font-size: 30rpx;
  585. text-align: center;
  586. }
  587. .batch-btn {
  588. display: flex;
  589. justify-content: center;
  590. align-items: center;
  591. width: 400rpx;
  592. height: 76rpx;
  593. background: #000000;
  594. border-radius: 38rpx;
  595. font-size: 34rpx;
  596. font-family: PingFang SC;
  597. font-weight: 500;
  598. color: #ffffff;
  599. margin: 40rpx auto 20rpx;
  600. }
  601. }
  602. </style>