arrts.vue 16 KB

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