多租户商城-商户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

523 lines
18 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <div class="addGroupBuy">
  3. <!-- 新增用户 -->
  4. <div class="addGroupBuyBox">
  5. <el-form ref="ruleForm" class="formBox" :model="addForm" label-width="150px" :rules="seckillBuyRules" :disabled="visitDetail">
  6. <div class="flexBox">
  7. <el-form-item label="活动名称" prop="seckillName">
  8. <el-input v-model="addForm.seckillName" maxlength="15" placeholder="请输入活动名称" />
  9. </el-form-item>
  10. </div>
  11. <div class="flexBox">
  12. <el-form-item label="备注">
  13. <el-input v-model="addForm.remark" maxlength="200" placeholder="请输入备注" />
  14. </el-form-item>
  15. </div>
  16. <el-form-item class="timeDataBox" label="活动时间">
  17. <div class="dateBox">
  18. <el-form-item>
  19. <el-date-picker
  20. v-model="dateInfo"
  21. type="datetimerange"
  22. :range-separator="$t('common.betweentime')"
  23. :start-placeholder="$t('common.startdate')"
  24. :end-placeholder="$t('common.enddate')"
  25. value-format="yyyy-MM-dd HH:mm:ss"
  26. />
  27. </el-form-item>
  28. </div>
  29. </el-form-item>
  30. <el-form-item class="boxWidth" label="商品限购" prop="proQuota">
  31. <el-radio v-model="addForm.ifLimit" label="1">不限购</el-radio>
  32. <el-radio v-model="addForm.ifLimit" label="2">限购</el-radio>
  33. <el-input v-model="addForm.limitNumber" maxlength="9" :disabled="addForm.ifLimit === '1'" oninput="value=value.replace(/[^\d]/g,'')" />/
  34. </el-form-item>
  35. <el-form-item class="boxWidth" label="活动商品限量" prop="proQuota">
  36. <el-radio v-model="addForm.ifNumber" label="0">不限量</el-radio>
  37. <el-radio v-model="addForm.ifNumber" label="1">限量</el-radio>
  38. <el-input v-model="addForm.number" maxlength="9" :disabled="addForm.ifNumber === '0'" oninput="value=value.replace(/[^\d]/g,'')" />
  39. </el-form-item>
  40. <el-form-item class="boxWidth" label="活动预热" prop="preheat">
  41. <el-radio v-model="addForm.ifEnable" label="1">停用</el-radio>
  42. <el-radio v-model="addForm.ifEnable" label="2">启用</el-radio>
  43. <el-input v-model="addForm.enableTime" maxlength="9" :disabled="addForm.ifEnable === '1'" oninput="value=value.replace(/[^\d]/g,'')" />小时前
  44. </el-form-item>
  45. <el-form-item label="优惠券叠加" prop="overlying">
  46. <el-radio v-model="addForm.ifAdd" label="1">叠加</el-radio>
  47. <el-radio v-model="addForm.ifAdd" label="0">不叠加</el-radio>
  48. </el-form-item>
  49. <el-form-item class="applyType" label="活动商品" prop="commodity">
  50. <span class="selectBtn" @click="chooseProduct"><span v-if="!visitDetail">{{$t('common.choose')}}</span><span v-else>查看商品</span><i v-if="addForm.details.length !== 0" class="selectNum">{{ addForm.details.length }}</i></span>
  51. </el-form-item>
  52. </el-form>
  53. </div>
  54. <span slot="footer" class="dialog-footer">
  55. <el-button v-show="!visitDetail" type="primary" @click="addSeckillFn('ruleForm')">{{ $t('common.save') }}</el-button>
  56. <!-- <el-button v-if="visitDetail" type="primary" @click="goToSpike">{{ $t('common.cancel') }}</el-button>-->
  57. <el-button @click="goToSpike">{{ $t('common.cancel') }}</el-button>
  58. </span>
  59. <!-- 新建分组弹框 -->
  60. <el-dialog
  61. :title="visitDetail ? '查看商品' : '选择商品'"
  62. :visible.sync="isVisible"
  63. width="75%"
  64. top="50px"
  65. class="group-dialog"
  66. :close-on-click-modal="false"
  67. :modal-append-to-body="false"
  68. :modal="false"
  69. >
  70. <!-- 表格 -->
  71. <div class="tableBox">
  72. <div style="margin-bottom: 15px">
  73. <el-input v-model="prodSearch" :placeholder="$t('product.productname_hint')" style="width: 360px"/>
  74. <el-button type="primary" style="margin-left: 8px" @click="searchProd">{{$t('common.query')}}</el-button>
  75. </div>
  76. <el-table
  77. ref="multipleTable"
  78. :data="tableData"
  79. border
  80. :header-cell-style="{ background: '#EEF3FF', color: '#333333' }"
  81. tooltip-effect="dark"
  82. style="width: 100%"
  83. :row-key="getRowKeys"
  84. max-height="600"
  85. @selection-change="handleSelectionChange"
  86. >
  87. <el-table-column
  88. v-if="!visitDetail"
  89. type="selection"
  90. :reserve-selection="true"
  91. width="55"
  92. />
  93. <el-table-column label="商品图片" width="150" align="center">
  94. <template slot-scope="scope">
  95. <img height="80" width="80" :src="scope.row.image " alt srcset>
  96. </template>
  97. </el-table-column>
  98. <el-table-column prop="productName" label="商品名称" show-overflow-tooltip/>
  99. <el-table-column prop="originalPrice" label="原价(元)" width="120" />
  100. <el-table-column prop="value" label="规格" width="120" />
  101. <el-table-column label="直降(元)" width="153">
  102. <template scope="scope">
  103. <el-input-number v-model="scope.row.downPrice" :disabled="visitDetail" size="small" :controls="false" :max="scope.row.originalPrice-0.01" :min="0.01" :precision="2" @input.native="changeCode(scope.row)" @blur="blurInput(scope.row)" />
  104. </template>
  105. </el-table-column>
  106. <el-table-column label="秒杀价(元)" width="150">
  107. <template scope="scope">
  108. <span v-if="scope.row.downPrice">{{ (scope.row.originalPrice - scope.row.downPrice).toFixed(2) }}</span>
  109. </template>
  110. </el-table-column>
  111. <el-table-column prop="stockNumber" label="库存" width="120" show-overflow-tooltip />
  112. <el-table-column prop="shopName" label="所属店铺" show-overflow-tooltip />
  113. <!-- <el-table-column width="80" :label="$t('common.operate')" show-overflow-tooltip>-->
  114. <!-- <template slot-scope="scope">-->
  115. <!-- <div class="btnList">-->
  116. <!-- <el-popconfirm title="确定删除此活动?" @onConfirm="deleteSeckillFn(scope.row)">-->
  117. <!-- <el-button slot="reference" class="delCls" type="text">{{ $t('common.delete') }}</el-button>-->
  118. <!-- </el-popconfirm>-->
  119. <!-- </div>-->
  120. <!-- </template>-->
  121. <!-- </el-table-column>-->
  122. </el-table>
  123. <div class="fenye">
  124. <el-pagination
  125. :current-page="proOption.page"
  126. :page-sizes="[10, 20, 50, 100]"
  127. :page-size="proOption.pageSize"
  128. layout="total, sizes, prev, pager, next, jumper"
  129. :total="total"
  130. @size-change="handleSizeChange"
  131. @current-change="handleCurrentChange"
  132. />
  133. </div>
  134. <div class="footBtnBox">
  135. <span slot="footer">
  136. <el-button v-if="!visitDetail" type="primary" @click="saveIdList">{{ $t('common.sure') }}</el-button>
  137. <el-button @click="closeSelect">{{ $t('common.cancel') }}</el-button>
  138. </span>
  139. </div>
  140. </div>
  141. </el-dialog>
  142. </div>
  143. </template>
  144. <script>
  145. import { addSeckill, getSpikeList, seckillUpdate, seckillDetail } from '@/api/marketing'
  146. function InitSpikeForm() {
  147. this.details = [] // 商品明细数据
  148. this.enableTime = '' // 预热几小时前
  149. this.effectiveEnd = '' // 秒杀活动结束时间
  150. this.seckillName = '' // 秒杀活动名称
  151. this.ifAdd = '1' // 优惠券是否叠加 1-是 0-否
  152. this.ifEnable = '1' // 秒杀活动预热 1-停用 2-启用
  153. this.ifLimit = '1' // 商品限购 1-不限购 2-限购
  154. this.limitNumber = '' // 限购几件/人
  155. this.person = null // 成团人数
  156. this.remark = '' // 备注
  157. this.ifNumber = '0' // 是否限量
  158. this.number = null // 限制数量
  159. this.effectiveStart = '' // 活动开始时间
  160. }
  161. export default {
  162. name: 'AddGroupBuy',
  163. props: {
  164. spikeId: {
  165. type: Number,
  166. default: 0
  167. },
  168. visitDetail: {
  169. type: Boolean,
  170. default: false
  171. }
  172. },
  173. data() {
  174. return {
  175. // 新增
  176. getRowKeys(row) {
  177. return row.skuId
  178. },
  179. addForm: new InitSpikeForm(),
  180. dateInfo: [], // 时间选择数组
  181. proOption: {
  182. page: 1,
  183. pageSize: 10
  184. },
  185. details: [],
  186. total: 0,
  187. tableData: [],
  188. shopSeckillId: '', // 秒杀ID
  189. seckillBuyRules: {
  190. seckillName: [
  191. { required: true, message: '请输入活动名称', trigger: 'blur' }
  192. ]
  193. },
  194. multipleSelection: [],
  195. roleList: [],
  196. isVisible: false, // 选择商品弹窗
  197. inputSpikeTableData: [],
  198. prodSearch: undefined
  199. }
  200. },
  201. watch: {
  202. spikeId: {
  203. handler(nVal, oVal) {
  204. this.shopSeckillId = nVal
  205. if (!nVal) {
  206. this.dateInfo = []
  207. this.inputSpikeTableData = []
  208. this.addForm = new InitSpikeForm()
  209. } else {
  210. this.getSeckillInfo()
  211. }
  212. }
  213. }
  214. },
  215. mounted() {
  216. this.getProList()
  217. this.shopSeckillId = this.spikeId
  218. if (this.shopSeckillId) {
  219. this.getSeckillInfo()
  220. }
  221. },
  222. methods: {
  223. // 重制表单数据
  224. resetData() {
  225. if (this.shopSeckillId === 0) {
  226. this.addForm = new InitSpikeForm()
  227. this.dateInfo = []
  228. this.inputSpikeTableData = []
  229. }
  230. if (this.$refs.multipleTable) {
  231. this.$refs.multipleTable.clearSelection()
  232. }
  233. },
  234. blurInput(data) {
  235. console.log(data, 'data')
  236. const index = this.inputSpikeTableData.findIndex(item => item.skuId === data.skuId)
  237. if (index === -1) {
  238. this.inputSpikeTableData.push(data)
  239. } else {
  240. this.inputSpikeTableData[index].downPrice = data.downPrice
  241. }
  242. },
  243. addSeckillFn(ruleForm) {
  244. this.$refs[ruleForm].validate(valid => {
  245. if (valid) {
  246. if (this.dateInfo.length === 0) {
  247. this.$message.warning('请选择用券时间开始和结束日期')
  248. return false
  249. }
  250. if (this.addForm.ifLimit === '2' && this.addForm.limitNumber === '' || this.addForm.limitNumber === '0') {
  251. this.$message.warning('请填写正确的活动限购数')
  252. return false
  253. }
  254. if (this.addForm.ifNumber === '2' && this.addForm.number === '' || this.addForm.number === '0') {
  255. this.$message.warning('请填写正确的活动限制数量')
  256. return false
  257. }
  258. if (this.addForm.ifEnable === '2' && this.addForm.enableTime === '' || this.addForm.enableTime === '0') {
  259. this.$message.warning('请填写正确的活动预热前时间')
  260. return false
  261. }
  262. this.addForm.effectiveStart = this.dateInfo[0]
  263. this.addForm.effectiveEnd = this.dateInfo[1]
  264. if (this.shopSeckillId) {
  265. seckillUpdate(this.addForm).then(res => {
  266. if (res.code === '') {
  267. this.$message.success(this.$t('common.editsuccessful'))
  268. this.addForm = new InitSpikeForm()
  269. this.dateInfo = []
  270. this.$emit('reset')
  271. } else {
  272. this.$message.error(res.message)
  273. }
  274. })
  275. } else {
  276. addSeckill(this.addForm).then(res => {
  277. if (res.code === '') {
  278. this.$message.success(this.$t('common.addsuccessful'))
  279. this.addForm = new InitSpikeForm()
  280. this.dateInfo = []
  281. this.$emit('reset')
  282. } else {
  283. this.$message.error(res.message)
  284. }
  285. })
  286. }
  287. } else {
  288. console.log('error submit!!')
  289. return false
  290. }
  291. })
  292. },
  293. changeCode(item) {
  294. this.$nextTick(() => {
  295. if (item.downPrice >= item.originalPrice) {
  296. item.downPrice = item.originalPrice - 0.01
  297. }
  298. })
  299. },
  300. handleSizeChange(val) {
  301. this.proOption.pageSize = val
  302. this.getProList()
  303. },
  304. handleCurrentChange(val) {
  305. this.proOption.page = val
  306. this.getProList()
  307. },
  308. // 选择商品
  309. chooseProduct(type) {
  310. this.isVisible = true
  311. if (this.visitDetail) {
  312. this.proOption.activityId = this.shopSeckillId
  313. } else {
  314. this.proOption.activityId = null
  315. }
  316. this.getProList()
  317. },
  318. getProList() {
  319. getSpikeList(this.proOption).then(res => {
  320. if (res.code === '') {
  321. const dataList = res.data.list
  322. if (this.inputSpikeTableData.length > 0) {
  323. dataList.forEach(item => {
  324. const index = this.inputSpikeTableData.findIndex(cItem => cItem.skuId === item.skuId)
  325. if (index !== -1) {
  326. item.downPrice = this.inputSpikeTableData[index].downPrice
  327. }
  328. })
  329. }
  330. this.tableData = dataList
  331. this.total = res.data.total
  332. // if (this.$refs.multipleTable) {
  333. // for (let i = 0; i < this.tableData.length; i++) {
  334. // for (let j = 0; j < this.addForm.details.length; j++) {
  335. // if (this.tableData[i].productId === this.addForm.details[j].productId && this.tableData[i].skuId === this.addForm.details[j].skuId) {
  336. // this.$refs.multipleTable.toggleRowSelection(this.tableData[i]);
  337. // }
  338. // }
  339. // }
  340. // }
  341. }
  342. })
  343. },
  344. // 选中商品
  345. handleSelectionChange(val) {
  346. this.multipleSelection = val
  347. },
  348. // 保存选择商品ID
  349. saveIdList() {
  350. try {
  351. const idList = []
  352. this.multipleSelection.forEach(item => {
  353. if (!item.downPrice) {
  354. this.$message.warning('请输入价格')
  355. throw new Error()
  356. }
  357. idList.push({
  358. downPrice: item.downPrice,
  359. seckillPrice: item.originalPrice - item.downPrice,
  360. productId: item.productId,
  361. skuId: item.skuId
  362. })
  363. })
  364. this.addForm.details = idList
  365. this.isVisible = false
  366. } catch (e) {
  367. console.log(e)
  368. }
  369. },
  370. // 取消选择
  371. closeSelect() {
  372. this.isVisible = false
  373. },
  374. // 跳转秒杀列表
  375. goToSpike() {
  376. this.$emit('reset')
  377. },
  378. async getSeckillInfo() {
  379. const res = await seckillDetail({ shopSeckillId: this.shopSeckillId })
  380. this.addForm.ifEnable = res.data.ifEnable.toString()
  381. this.addForm.enableTime = res.data.enableTime
  382. this.addForm.effectiveTime = res.data.effectiveTime
  383. this.addForm.seckillName = res.data.seckillName
  384. this.addForm.effectiveStart = res.data.effectiveStart
  385. this.addForm.effectiveEnd = res.data.effectiveEnd
  386. this.addForm.person = res.data.person
  387. this.addForm.ifAdd = res.data.ifAdd.toString()
  388. this.addForm.ifNumber = res.data.ifNumber.toString()
  389. this.addForm.ifLimit = res.data.ifLimit.toString()
  390. this.addForm.number = res.data.number
  391. this.addForm.limitNumber = res.data.limitNumber
  392. this.addForm.remark = res.data.remark
  393. this.addForm.shopSeckillId = res.data.shopSeckillId
  394. const idList = res.data.products
  395. idList.forEach(i => {
  396. this.addForm.details.push({
  397. downPrice: i.downPrice,
  398. seckillPrice: i.originalPrice - i.downPrice,
  399. productId: i.productId,
  400. skuId: i.skuId
  401. })
  402. })
  403. this.dateInfo = [this.addForm.effectiveStart, this.addForm.effectiveEnd]
  404. },
  405. // 删除
  406. deleteSeckillFn() {
  407. },
  408. searchProd() {
  409. this.proOption.page = 1
  410. this.proOption.pageSize = 10
  411. this.proOption.searchContent = this.prodSearch
  412. this.getProList()
  413. }
  414. }
  415. }
  416. </script>
  417. <style lang='scss' scoped>
  418. //@import url(); 引入公共css类
  419. @import url("../../../styles/elDialog.scss");
  420. .addGroupBuy {
  421. padding: 0px;
  422. .formBox {
  423. margin-top: 20px;
  424. .flexBox {
  425. display: flex;
  426. }
  427. .applyType {
  428. span {
  429. width: 100px;
  430. height: 30px;
  431. line-height: 30px;
  432. background: #66b1ff;
  433. color: #FFFFFF;
  434. text-align: center;
  435. display: inline-block;
  436. font-size: 14px;
  437. margin-right: 30px;
  438. border-radius: 4px;
  439. cursor: pointer;
  440. position: relative;
  441. i {
  442. position: absolute;
  443. right: -10px;
  444. top: -10px;
  445. width: 25px;
  446. height: 25px;
  447. line-height: 25px;
  448. background: #FFFFFF;
  449. border-radius: 50%;
  450. border: 1px solid #66b1ff;
  451. text-align: center;
  452. color: #409EFF;
  453. font-style: normal;
  454. font-size: 12px;
  455. }
  456. }
  457. }
  458. }
  459. .footBtnBox {
  460. width: 100%;
  461. display: flex;
  462. justify-content: center;
  463. margin-top: 50px;
  464. }
  465. .dateBox {
  466. display: flex;
  467. align-items: center;
  468. .description {
  469. width: 59px;
  470. text-align: center;
  471. display: block;
  472. font-size: 14px;
  473. color: #999999;
  474. }
  475. }
  476. }
  477. </style>
  478. <style scoped>
  479. .flexBox /deep/ .el-input {
  480. width: 500px;
  481. }
  482. .inputW /deep/ .el-input {
  483. width: 100px;
  484. margin: 0 8px 0 0;
  485. }
  486. .inputW /deep/ .el-input .el-input__inner {
  487. text-align: center;
  488. }
  489. .inputW /deep/ .el-form-item__error {
  490. padding-left: 0;
  491. }
  492. .inputW /deep/ .el-checkbox {
  493. margin-left: 20px;
  494. }
  495. .inputW /deep/ .el-radio {
  496. margin-left: 30px;
  497. }
  498. .boxWidth /deep/ .el-input {
  499. width: 100px;
  500. margin-right: 15px;
  501. }
  502. .boxWidth /deep/ .el-input .el-input__inner {
  503. text-align: center;
  504. }
  505. .addGroupBuy .timeDataBox /deep/ .el-form-item__content {
  506. display: flex;
  507. align-items: center;
  508. }
  509. input::-webkit-outer-spin-button,
  510. input::-webkit-inner-spin-button {
  511. -webkit-appearance: none;
  512. }
  513. input[type="number"]{
  514. -moz-appearance: textfield;
  515. }
  516. </style>