多租户商城-商户端
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.

507 lines
17 KiB

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