index.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. <?php
  2. use common\helpers\ComponentHelper;
  3. ComponentHelper::loadComponentView('com-dialog-select');
  4. ?>
  5. <div id="app" v-cloak>
  6. <el-card shadow="never" style="border:0;min-width: 1000px;" body-style="background-color: #f3f3f3;padding: 10px 0 0;" v-loading="loading">
  7. <div slot="header">
  8. <span>活动列表</span>
  9. </div>
  10. <div class="table-body">
  11. <div class="search-item">
  12. <el-select v-model="search.activity_status" clearable placeholder="状态选项" @change="toSearch">
  13. <el-option v-for="item in statusList" :key="item.status" :label="item.value"
  14. :value="item.status" >
  15. </el-option>
  16. </el-select>
  17. </div>
  18. <div class="search-item">
  19. <el-date-picker v-model="time" type="daterange" range-separator="至"
  20. start-placeholder="开始日期" end-placeholder="结束日期" @change="timeChange" value-format="yyyy-MM-dd HH:mm:ss">
  21. </el-date-picker>
  22. </div>
  23. <el-button type="primary" size="small" icon="el-icon-search" style="padding: 9px 15px !important;" @click="toSearch">搜索</el-button>
  24. <el-button size="small" icon="el-icon-refresh-right" style="padding: 9px 15px !important;" @click="reset">重置</el-button>
  25. <div style="float: right">
  26. <el-button type="primary" size="small" icon="el-icon-plus" style="padding: 9px 15px !important;" @click="addbox">新建活动
  27. </el-button>
  28. </div>
  29. <el-table :data="list" stripe v-loading="loading" size="small" style="margin: 15px 0;">
  30. <el-table-column prop="id" width="50" align="center"></el-table-column>
  31. <el-table-column prop="title" label="活动名称" align="center"></el-table-column>
  32. <el-table-column label="商品信息" prop="goods_name" align="center">
  33. <template slot-scope="scope">
  34. <div flex="cross:center">
  35. <div style="margin-right: 10px;">
  36. <el-image style="width: 50px; height: 50px;border-radius: 5px;" :src="scope.row.cover_pic"></el-image>
  37. </div>
  38. <el-tooltip class="item" effect="dark" :content="scope.row.goods_name" placement="top">
  39. <span class="over2">{{scope.row.goods_name}}</span>
  40. </el-tooltip>
  41. </div>
  42. </template>
  43. </el-table-column>
  44. <el-table-column prop="hot_time" label="活动预热时间" align="center">
  45. </el-table-column>
  46. <el-table-column prop="begin_time" label="活动开始时间" align="center">
  47. </el-table-column>
  48. <el-table-column prop="end_time" label="活动结束时间" align="center">
  49. </el-table-column>
  50. <el-table-column prop="now_stock" label="剩余库存" align="center"></el-table-column>
  51. <el-table-column prop="activity_status_msg" label="活动当前状态" align="center">
  52. <!-- <template slot-scope="scope">
  53. </template> -->
  54. </el-table-column>
  55. <el-table-column prop="price" label="秒杀价格" align="center"></el-table-column>
  56. <el-table-column prop="user_id" width="140" label="操作" align="center">
  57. <template slot-scope="scope">
  58. <el-tooltip class="item" effect="dark" content="详情" placement="top-start">
  59. <el-button size="mini" type="primary" icon="el-icon-s-unfold" circle @click="details(scope.row.id)"></el-button>
  60. </el-tooltip>
  61. <el-button size="mini" type="primary" icon="el-icon-edit" circle @click="editbox(scope.row.id)"></el-button>
  62. <el-button size="mini" type="danger" icon="el-icon-delete" circle @click="del(scope.row.id)"></el-button>
  63. </template>
  64. </el-table-column>
  65. </el-table>
  66. <div flex="box:last cross:center">
  67. <div></div>
  68. <div>
  69. <el-pagination
  70. v-if="list.length > 0"
  71. style="display: inline-block;float: right;"
  72. background :page-size="pageSize"
  73. @current-change="pageChange"
  74. layout="prev, pager, next" :current-page="current_page"
  75. :total="totalCount">
  76. </el-pagination>
  77. </div>
  78. </div>
  79. </div>
  80. </el-card>
  81. <!-- 新建/编辑弹层 -->
  82. <el-dialog :title="activityType == 'add' ? '新建活动' : '编辑活动'" :visible.sync="activityShow"width="800px" @open="activityOpen" @close="activityReset('dynamicValidateForm')">
  83. <div>
  84. <el-form :model="form" ref="dynamicValidateForm" label-width="120px" class="demo-dynamic">
  85. <el-form-item prop="begin_time" label="活动开始时间"
  86. :rules="[{ required: true, message: '请选择活动开始时间', trigger: 'blur' }]">
  87. <el-date-picker
  88. v-model="form.begin_time"
  89. type="datetime"
  90. value-format="yyyy-MM-dd HH:mm:ss"
  91. placeholder="选择日期">
  92. </el-date-picker>
  93. </el-form-item>
  94. <el-form-item prop="end_time" label="活动结束时间"
  95. :rules="[{ required: true, message: '请选择活动结束时间', trigger: 'blur' }]">
  96. <el-date-picker
  97. v-model="form.end_time"
  98. type="datetime"
  99. value-format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
  100. placeholder="选择日期">
  101. </el-date-picker>
  102. </el-form-item>
  103. <el-form-item prop="hot_time" label="活动预热时间"
  104. :rules="[{ required: true, message: '请选择活动预热时间', trigger: 'blur' }]">
  105. <el-date-picker
  106. v-model="form.hot_time"
  107. type="datetime"
  108. value-format="yyyy-MM-dd HH:mm:ss"
  109. placeholder="选择日期">
  110. </el-date-picker>
  111. </el-form-item>
  112. <el-form-item label="选择商品" prop="goods_id" :rules="[{ required: true, message: '请选择商品', trigger: 'blur' }]">
  113. <com-dialog-select v-model="goods_id" :multiple="false" url="mall/goods/search"
  114. @selected="selectGoodsWarehouse" ref="comDialogSelect"
  115. :params="{is_achievement: 1}" :show-mch-source="true" :extra-search-fields="['goods_source']">
  116. <el-button>选择商品</el-button>
  117. </com-dialog-select>
  118. </el-form-item>
  119. <el-form-item v-if="formGoodsList.length>0" label="选中商品">
  120. <div class="table-body">
  121. <template>
  122. <el-table
  123. :data="formGoodsList"
  124. border
  125. style="width: 680px">
  126. <el-table-column
  127. label="商品"
  128. min-width="400">
  129. <template slot-scope="scope">
  130. <div flex="box:first">
  131. <div style="padding-right: 10px;">
  132. <com-image mode="aspectFill" :src="scope.row.cover_pic"></com-image>
  133. </div>
  134. <div>
  135. <div>
  136. {{scope.row.goods_name}}
  137. </div>
  138. <div>
  139. <span style="color:red;margin-right: 10px;">
  140. ¥{{scope.row.price}}
  141. </span>
  142. <span>
  143. 库存:{{scope.row.stock}}
  144. </span>
  145. </div>
  146. </div>
  147. </div>
  148. </template>
  149. </el-table-column>
  150. <el-table-column label="操作" min-width="150" align="center">
  151. <template slot-scope="scope">
  152. <el-button @click="delGoods" type="text" size="small">删除</el-button>
  153. </template>
  154. </el-table-column>
  155. </el-table>
  156. </template>
  157. </div>
  158. </el-form-item>
  159. <el-form-item label="商品型号" prop="attr_id" :rules="[{ required: true, message: '请选择商品型号', trigger: 'blur' }]">
  160. <el-select v-model="form.attr_id" placeholder="请选择">
  161. <el-option
  162. v-for="item in goodattrlist"
  163. :key="item.id"
  164. :label="item.name"
  165. :value="item.id">
  166. </el-option>
  167. </el-select>
  168. </el-form-item>
  169. <el-form-item label="设置库存" prop="stock" :rules="[{ required: true, message: '请设置库存', trigger: 'blur' }]">
  170. <el-input-number :min="0" v-model="form.stock"></el-input-number>
  171. </el-form-item>
  172. <el-form-item label="秒杀售价" prop="price" :rules="[{ required: true, message: '请输入秒杀售价', trigger: 'blur' }]">
  173. <el-input-number :min="0" v-model="form.price"></el-input-number>
  174. </el-form-item>
  175. <el-form-item label="每人限购" prop="limit_nums" prop="price">
  176. <el-input-number :min="0" v-model="form.limit_nums"></el-input-number>
  177. <div class="tips-text" >限制每个用户最多购买商品数(0或空为不做限制)</div>
  178. </el-form-item>
  179. <el-form-item label="活动名称" prop="title" :rules="[{ required: true, message: '请输入活动名称', trigger: 'blur' }]">
  180. <el-input
  181. type="textarea"
  182. placeholder="请输入内容"
  183. v-model="form.title">
  184. </el-input>
  185. </el-form-item>
  186. </el-form>
  187. </div>
  188. <span slot="footer" class="dialog-footer">
  189. <el-button @click="activityCancel('dynamicValidateForm')">取 消</el-button>
  190. <el-button @click="activityReset('dynamicValidateForm')">重 置</el-button>
  191. <el-button type="primary" @click="addActivity('dynamicValidateForm')">确 定</el-button>
  192. </span>
  193. </el-dialog>
  194. </div>
  195. <script>
  196. const app = new Vue({
  197. el: '#app',
  198. data: {
  199. statusList:[],
  200. time:'',
  201. loading: false,
  202. search: {
  203. activity_status:'',
  204. search_begin_time:'',
  205. search_end_time:'',
  206. page: this.current_page
  207. },
  208. form: {
  209. title:'',
  210. goods_id:'',
  211. attr_id:'',
  212. begin_time:'',
  213. end_time:'',
  214. stock:'',
  215. hot_time:'',
  216. price:'',
  217. limit_nums: '0',
  218. },
  219. goods_id:'',
  220. edit: {
  221. },
  222. goodattrlist:[],
  223. list:[],
  224. statusList:[],
  225. loading:false,
  226. activityShow:false, // 活动弹层
  227. activityType: '', // 活动弹层类型
  228. activityId: 0, // 活动id
  229. pageSize:20,
  230. current_page:1,
  231. totalCount:0,
  232. formGoodsList:[],
  233. goods_price:'',
  234. },
  235. mounted() {
  236. this.getDataList()
  237. },
  238. methods: {
  239. // 获取数据
  240. getDataList(search = {}) {
  241. this.loading = true;
  242. request({
  243. params: {
  244. r: '/seckill/activity/list',
  245. ...search
  246. },
  247. method: 'get',
  248. }).then(e => {
  249. console.log(e,'77777777777');
  250. this.list = e.data.data.list
  251. this.pageSize = e.data.data.page_size
  252. this.totalCount = e.data.data.count
  253. let arr = Object.values(e.data.data.status_map).map((item,index)=> {
  254. return {
  255. "status": index + 1,
  256. "value": item
  257. }
  258. })
  259. console.log(arr);
  260. this.statusList = arr
  261. this.loading = false;
  262. }).catch(e => {
  263. this.loading = false;
  264. });
  265. },
  266. // 弹层重置
  267. activityReset(formName) {
  268. this.$refs[formName].resetFields();
  269. },
  270. activityCancel(formName) {
  271. this.form.id = 0;
  272. this.activityShow = false
  273. },
  274. // 新建活动
  275. addActivity(formName) {
  276. console.log(this.form,'-------');
  277. this.$refs[formName].validate((valid) => {
  278. if (valid) {
  279. // 添加提交
  280. console.log(this.form.goods_id);
  281. if(this.activityId){
  282. this.form.id = this.activityId
  283. }
  284. // this.form.goods_id = this.form.goods_id.id
  285. request({
  286. method: 'post',
  287. params: {
  288. r: '/seckill/activity/save',
  289. },
  290. data: this.form
  291. }).then(res => {
  292. console.log(res);
  293. if (res.data.code == 0) {
  294. this.$message.success('添加成功');
  295. this.activityShow = false
  296. this.getDataList()
  297. } else {
  298. this.$message.error(res.data.msg);
  299. }
  300. }).catch(e => {
  301. console.log(e);
  302. });
  303. } else {
  304. return false;
  305. }
  306. });
  307. },
  308. // 活动打开
  309. activityOpen() {
  310. console.log(this.activityType);
  311. if(this.activityType == 'edit') {
  312. // 数据回显
  313. console.log(this.activityId);
  314. request({
  315. params: {
  316. r: '/seckill/activity/info',
  317. id: this.activityId
  318. }
  319. }).then(res => {
  320. if (res.data.code == 0) {
  321. console.log(res.data.data.goods.goods_id,'444444444444');
  322. this.formGoodsList = [res.data.data.goods]
  323. this.goodattrlist = [res.data.data.goods_attr]
  324. this.form.title = res.data.data.title
  325. this.form.goods_id = res.data.data.goods.goods_id
  326. this.form.attr_id = res.data.data.goods_attr.id
  327. this.form.price = res.data.data.price
  328. this.form.stock = res.data.data.stock
  329. this.form.begin_time = res.data.data.begin_time
  330. this.form.end_time = res.data.data.end_time
  331. this.form.hot_time = res.data.data.hot_time
  332. this.form.limit_nums = res.data.data.limit_nums
  333. console.log(this.form,'55555555');
  334. } else {
  335. this.$message.error(res.data.msg);
  336. }
  337. }).catch(e => {
  338. console.log(e);
  339. });
  340. }else {
  341. this.formGoodsList = []
  342. this.goodattrlist = []
  343. this.form = {
  344. title:'',
  345. goods_id:'',
  346. attr_id:'',
  347. begin_time:'',
  348. end_time:'',
  349. stock:'',
  350. hot_time:'',
  351. price:'',
  352. id : 0,
  353. }
  354. }
  355. },
  356. addbox() {
  357. this.activityType = 'add'
  358. this.activityShow = true
  359. this.activityId = 0
  360. },
  361. editbox(id) {
  362. this.activityType = 'edit'
  363. this.activityId = id
  364. this.activityShow = true
  365. },
  366. details(id) {
  367. navigateTo({
  368. r: 'seckill/order/index',
  369. id,
  370. });
  371. },
  372. del(id) {
  373. let self = this;
  374. self.$confirm('删除该活动, 是否继续?', '提示', {
  375. confirmButtonText: '确定',
  376. cancelButtonText: '取消',
  377. type: 'warning'
  378. }).then(() => {
  379. request({
  380. params: {
  381. r: '/seckill/activity/delete',
  382. },
  383. method: 'post',
  384. data: {
  385. id
  386. }
  387. }).then(e => {
  388. if (e.data.code === 0) {
  389. self.$message.success(e.data.msg);
  390. self.getDataList()
  391. } else {
  392. self.$message.error(e.data.msg);
  393. }
  394. }).catch(e => {
  395. console.log(e);
  396. });
  397. }).catch(() => {
  398. self.$message.info('已取消删除')
  399. });
  400. },
  401. selectGoodsWarehouse(v) {
  402. console.log(v,'商品选中9999999');
  403. this.formGoodsList = [];
  404. this.goods_price = v.price;
  405. this.formGoodsList.push(v);
  406. this.form.goods_id = v.id;
  407. //先验证商品
  408. this.$refs.dynamicValidateForm.validateField('goods_id');
  409. console.log(this.form.goods_id,'111111111111');
  410. this.getattrlist(v.id)
  411. },
  412. getattrlist(id) {
  413. request({
  414. params: {
  415. r: '/seckill/activity/get-goods-attr',
  416. goods_id:id
  417. }
  418. }).then(res => {
  419. if (res.data.code == 0) {
  420. console.log(res.data,'7777777777777777');
  421. this.goodattrlist = res.data.data
  422. } else {
  423. this.$message.error(res.data.msg);
  424. }
  425. }).catch(e => {
  426. });
  427. },
  428. delGoods() {
  429. this.formGoodsList = [];
  430. this.form.goods_id = '';
  431. //先验证商品
  432. this.$refs.dynamicValidateForm.validateField('goods_id');
  433. // 去除商品选中值
  434. this.$refs['comDialogSelect'].radioSelection = null;
  435. this.$refs['comDialogSelect'].multipleSelection = [];
  436. },
  437. timeChange(v) {
  438. console.log(v,'time99999999999');
  439. if(v) {
  440. this.search.search_begin_time = v[0]
  441. this.search.search_end_time = v[1]
  442. }else {
  443. this.search.search_begin_time = ''
  444. this.search.search_end_time = ''
  445. }
  446. },
  447. // 切换分页
  448. pageChange(v) {
  449. this.search.page = v
  450. this.getDataList(this.search)
  451. },
  452. // 搜索
  453. toSearch() {
  454. this.getDataList(this.search)
  455. },
  456. // 重置
  457. reset() {
  458. this.search = {
  459. status:'',
  460. time:''
  461. },
  462. this.getDataList()
  463. },
  464. timeformat(v) {
  465. let time = new Date(v*1000)
  466. return time.getFullYear() +'/'+(time.getUTCMonth()+1)+'/'+time.getDate() + ' '+ (time.getHours()<10?'0' +time.getHours():time.getHours()) +':'+ (time.getMinutes()<10?'0'+time.getMinutes():time.getMinutes()) + ':'+ (time.getSeconds()<10?'0'+time.getSeconds():time.getSeconds())
  467. },
  468. },
  469. })
  470. </script>
  471. <style>
  472. .search-item {
  473. display: inline-block;
  474. margin: 0 20px 0 0 ;
  475. }
  476. .red{
  477. color: #d9001b;
  478. }
  479. .orange {
  480. color: #f59a23;
  481. }
  482. .green {
  483. color: #4b7902;
  484. }
  485. </style>