index.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. <div id="app" v-cloak>
  2. <el-card shadow="never" style="border:0;min-width: 1000px;" body-style="background-color: #f3f3f3;padding: 10px 0 0;">
  3. <div slot="header">
  4. <span>提货管理</span>
  5. </div>
  6. <div class="table-body">
  7. <div>
  8. <el-form :inline="true" :model="search_data" size="small" class="demo-form-inline">
  9. <div class="flex">
  10. <el-form-item label="">
  11. <el-input placeholder="请输入小店ID|昵称" v-model="search_data.store_keyword"
  12. clearable></el-input>
  13. </el-form-item>
  14. <el-form-item label="提货时间">
  15. <el-date-picker v-model="dates" size="small" type="daterange" format="yyyy-MM-dd" value-format="yyyy-MM-dd" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" @change="selectedDates"> </el-date-picker>
  16. </el-form-item>
  17. <el-form-item>
  18. <el-button type="primary" @click="search">搜索</el-button>
  19. <el-button type="danger" @click="clearSearch" v-if="show_clear_search_btn">清除条件</el-button>
  20. </el-form-item>
  21. </div>
  22. </el-form>
  23. </div>
  24. <el-table :data="list" stripe v-loading="listLoading" size="small" style="margin-bottom: 15px; width: 100%">
  25. <el-table-column label="提货时间" width="200" prop="money">
  26. <template slot-scope="scope">
  27. <div v-if="scope.row.created_at>0">{{scope.row.created_at | dateTimeFormat('Y-m-d H:i:s')}}</div>
  28. </template>
  29. </el-table-column>
  30. <el-table-column prop="order_no" label="提货批次" align="center">
  31. <template slot-scope="scope">
  32. <div>{{scope.row.order_no}}</div>
  33. </template>
  34. </el-table-column>
  35. <el-table-column label="收货人信息" width="200" prop="money">
  36. <template slot-scope="scope">
  37. <div>收货人姓名: {{scope.row.user_name}}</div>
  38. <div>手机号: {{scope.row.mobile}}</div>
  39. <div>地址: {{scope.row.address}}</div>
  40. </template>
  41. </el-table-column>
  42. <el-table-column label="配送方式" align="center">
  43. <div>物流配送</div>
  44. </el-table-column>
  45. <el-table-column prop="store_id" label="小店ID" align="center"></el-table-column>
  46. <el-table-column label="小店名称" width="200" prop="store_name">
  47. <template slot-scope="scope">
  48. <div>{{scope.row.store.store_name}}</div>
  49. </template>
  50. </el-table-column>
  51. <el-table-column label="状态" width="200" prop="money">
  52. <template slot-scope="scope">
  53. <div>{{scope.row.order_status_text}}</div>
  54. </template>
  55. </el-table-column>
  56. <el-table-column label="操作" fixed="right" align="center" width="200">
  57. <template slot-scope="scope">
  58. <template>
  59. <el-button v-if="scope.row.order_status==0" type="text" size="small" @click="audit(scope.row)">审核</el-button>
  60. <el-button v-if="scope.row.order_status==1" type="text" size="small" @click="send(scope.row)">确认发货</el-button>
  61. <el-button v-if="scope.row.order_status==2" type="text" size="small" @click="send(scope.row)">继续发货</el-button>
  62. <el-button v-if="scope.row.order_status>=1" type="text" size="small" @click="express
  63. (scope.row)">发货详情</el-button>
  64. <el-button v-if="scope.row.order_status>=1" type="text" size="small" @click="showGoods(scope.row)">查看商品</el-button>
  65. </template>
  66. </template>
  67. </el-table-column>
  68. </el-table>
  69. <div style="text-align: right;margin: 20px 0;">
  70. <el-pagination @current-change="pagination" background layout="prev, pager, next" :page-count="pageCount"></el-pagination>
  71. </div>
  72. </div>
  73. <el-dialog title="是否允许提货" :visible.sync="dialogVisible" width="500px">
  74. <el-form :inline="true" :model="auditForm" size="small" class="demo-form-inline">
  75. <!--提货的商品-->
  76. <div>
  77. <el-table :data="detail.goods" stripe size="small" style="margin-bottom: 15px; width: 100%">
  78. <el-table-column label="商品图片" width="100">
  79. <template slot-scope="scope">
  80. <div v-if="scope.row.cover_pic">
  81. <img :src="scope.row.cover_pic" style="width: 50px;heightheight: 50px;">
  82. </div>
  83. </template>
  84. </el-table-column>
  85. <el-table-column label="商品名称" width="200">
  86. <template slot-scope="scope">
  87. <div>{{scope.row.goods_name}}{{scope.row.goods_attr_name}}</div>
  88. </template>
  89. </el-table-column>
  90. <el-table-column label="提货数量">
  91. <template slot-scope="scope">
  92. <div>{{scope.row.num}}件</div>
  93. </template>
  94. </el-table-column>
  95. </el-table>
  96. </div>
  97. <div style="margin-top: 20px">
  98. <el-input v-if="auditForm.status==0" placeholder="请输入备注" v-model="auditForm.remark" type="textarea"
  99. clearable></el-input>
  100. </div>
  101. <div style="margin-top: 20px;text-align: center">
  102. <el-radio-group v-model="auditForm.status">
  103. <el-radio label="1">允许提货</el-radio>
  104. <el-radio label="0">拒绝提货</el-radio>
  105. </el-radio-group>
  106. </div>
  107. <div style="margin-top: 20px;text-align: center">
  108. <el-button size="mini" type="primary" :loading="btnLoading" @click="handle('audit',auditForm)">提交</el-button>
  109. <el-button size="mini" @click="dialogVisible=false">取消</el-button>
  110. </div>
  111. </el-form>
  112. </el-dialog>
  113. <el-dialog title="确认发货" :visible.sync="dialogSendVisible" width="1200px">
  114. <el-form :inline="true" :model="sendForm" size="small" class="demo-form-inline">
  115. <el-form-item label="发货单号">
  116. <el-input size="small" v-model="sendForm.express_no" placeholder="请输入发货单号"></el-input>
  117. </el-form-item>
  118. <el-form-item label="物流公司">
  119. <el-input size="small" v-model="sendForm.express_company" placeholder="请输入物流公司"></el-input>
  120. </el-form-item>
  121. <el-table :data="sendForm.goods" stripe size="small" style="margin-bottom: 15px; width: 100%">
  122. <el-table-column label="商品图片" width="100">
  123. <template slot-scope="scope">
  124. <div v-if="scope.row.cover_pic">
  125. <img :src="scope.row.cover_pic" style="width: 50px;heightheight: 50px;">
  126. </div>
  127. </template>
  128. </el-table-column>
  129. <el-table-column label="商品名称" width="200">
  130. <template slot-scope="scope">
  131. <div>{{scope.row.goods_name}}{{scope.row.goods_attr_name}}</div>
  132. </template>
  133. </el-table-column>
  134. <el-table-column label="提货数量">
  135. <template slot-scope="scope">
  136. <div>{{scope.row.leave_num}}件</div>
  137. </template>
  138. </el-table-column>
  139. <el-table-column label="生产日期">
  140. <template slot-scope="scope">
  141. <el-date-picker size="small" style="width: 150px" v-model="scope.row.create_date"
  142. size="small"
  143. format="yyyy-MM-dd"
  144. value-format="yyyy-MM-dd"> </el-date-picker>
  145. </template>
  146. </el-table-column>
  147. <el-table-column label="保质期">
  148. <template slot-scope="scope">
  149. <el-input style="width: 100px" size="small" v-model="scope.row.save_day"
  150. type="number">
  151. </el-input>
  152. </template>
  153. </el-table-column>
  154. <el-table-column label="过期时间" >
  155. <template slot-scope="scope">
  156. <div v-if="scope.row.create_date && scope.row.save_day">
  157. <!-- 显示计算结果并同时更新数据模型 -->
  158. {{ updateAndShowExpireDate(scope.row, scope.$index) }}
  159. </div>
  160. <div v-else>
  161. {{ scope.row.expire_date }}
  162. </div>
  163. </template>
  164. </el-table-column>
  165. <el-table-column label="发货数量">
  166. <template slot-scope="scope">
  167. <el-input style="width: 100px" size="small" v-model="scope.row.send_num" placeholder="发货数量" :min="1"
  168. :max="scope.row.leave_num" type="number" clearable></el-input>
  169. </template>
  170. </el-table-column>
  171. </el-table>
  172. <div style="margin-top: 20px;text-align: center">
  173. <el-button size="mini" type="primary" :loading="btnLoading" @click="handle('send',sendForm)">提交</el-button>
  174. <el-button size="mini" @click="dialogSendVisible=false">取消</el-button>
  175. </div>
  176. </el-form>
  177. </el-dialog>
  178. <el-dialog title="发货详情" :visible.sync="dialogExpressVisible" width="1200px">
  179. <div v-for="(item,index) in express_list">
  180. <div style="margin-left: 10px"><span style="margin-right: 50px">物流单号:{{item
  181. .express_no}}</span><span>物流公司:{{item
  182. .express_company}}</span></div>
  183. <el-table :data="item.goods" stripe size="small" style="margin-bottom: 15px; width: 100%">
  184. <el-table-column label="商品图片" width="100">
  185. <template slot-scope="scope">
  186. <div v-if="scope.row.cover_pic">
  187. <img :src="scope.row.cover_pic" style="width: 50px;heightheight: 50px;">
  188. </div>
  189. </template>
  190. </el-table-column>
  191. <el-table-column label="商品名称" width="200">
  192. <template slot-scope="scope">
  193. <div>{{scope.row.goods_name}}{{scope.row.goods_attr_name}}</div>
  194. </template>
  195. </el-table-column>
  196. <el-table-column label="提货数量">
  197. <template slot-scope="scope">
  198. <div>{{scope.row.buy_num}}件</div>
  199. </template>
  200. </el-table-column>
  201. <el-table-column label="生产日期">
  202. <template slot-scope="scope">
  203. <div>{{scope.row.create_date | dateTimeFormat("Y-m-d")}}</div>
  204. </template>
  205. </el-table-column>
  206. <el-table-column label="保质期">
  207. <template slot-scope="scope">
  208. <div>{{scope.row.save_day}}天</div>
  209. </template>
  210. </el-table-column>
  211. <el-table-column label="过期时间" >
  212. <template slot-scope="scope">
  213. <div>{{scope.row.expire_date | dateTimeFormat("Y-m-d")}}</div>
  214. </template>
  215. </el-table-column>
  216. <el-table-column label="发货数量">
  217. <template slot-scope="scope">
  218. <div>{{scope.row.num}}</div>
  219. </template>
  220. </el-table-column>
  221. </el-table>
  222. </div>
  223. <div style="margin-top: 20px;text-align: center">
  224. <el-button size="mini" @click="dialogExpressVisible=false">取消</el-button>
  225. </div>
  226. </el-dialog>
  227. <el-dialog title="查看商品" :visible.sync="dialogGoodsVisible" width="1200px">
  228. <el-table :data="detail.goods" stripe size="small" style="margin-bottom: 15px; width: 100%">
  229. <el-table-column label="商品图片" width="100">
  230. <template slot-scope="scope">
  231. <div v-if="scope.row.cover_pic">
  232. <img :src="scope.row.cover_pic" style="width: 50px;heightheight: 50px;">
  233. </div>
  234. </template>
  235. </el-table-column>
  236. <el-table-column label="商品名称" width="200">
  237. <template slot-scope="scope">
  238. <div>{{scope.row.goods_name}}{{scope.row.goods_attr_name}}</div>
  239. </template>
  240. </el-table-column>
  241. <el-table-column label="提货数量">
  242. <template slot-scope="scope">
  243. <div>{{scope.row.num}}件</div>
  244. </template>
  245. </el-table-column>
  246. <el-table-column label="剩余待发数量">
  247. <template slot-scope="scope">
  248. <div>{{scope.row.leave_num}}</div>
  249. </template>
  250. </el-table-column>
  251. </el-table>
  252. <div style="margin-top: 20px;text-align: center">
  253. <el-button size="mini" @click="dialogGoodsVisible=false">取消</el-button>
  254. </div>
  255. </el-dialog>
  256. </el-card>
  257. </div>
  258. <script>
  259. const app = new Vue({
  260. el: '#app',
  261. data() {
  262. return {
  263. search_data: {
  264. store_keyword:'',
  265. start_time:'',
  266. end_time:''
  267. },
  268. btnLoading:false,
  269. list: [],
  270. dates: null,
  271. page: 1,
  272. pageCount: 0,
  273. listLoading: false,
  274. auditForm:{
  275. id:'',
  276. remark:'',
  277. status:'1',
  278. },
  279. sendForm:{
  280. id:'',
  281. express_company:'',
  282. express_no:'',
  283. goods:[]
  284. },
  285. detail:[],
  286. dialogVisible:false,
  287. dialogSendVisible:false,
  288. dialogExpressVisible:false,
  289. dialogGoodsVisible:false,
  290. express_list:[],
  291. };
  292. },
  293. mounted: function() {
  294. this.getList();
  295. },
  296. computed: {
  297. show_clear_search_btn: function() {
  298. return !isEmpty(this.search_data.store_keyword) || !isEmpty(this.search_data.start_time) || !isEmpty(this.search_data
  299. .end_time);
  300. }
  301. },
  302. methods: {
  303. // 添加更新并显示过期日期的方法
  304. updateAndShowExpireDate(row, index) {
  305. const expireDate = this.getComputedExpireDate(row.create_date, row.save_day);
  306. // 更新数据模型
  307. this.$set(this.sendForm.goods[index], 'expire_date', expireDate);
  308. // 返回显示值
  309. return expireDate;
  310. },
  311. // 计算过期日期显示值
  312. getComputedExpireDate(createDate, saveDay) {
  313. if (!createDate || !saveDay) return '';
  314. try {
  315. let date = new Date(createDate);
  316. date.setDate(date.getDate() + parseInt(saveDay));
  317. return date.toISOString().split('T')[0];
  318. } catch (e) {
  319. return '';
  320. }
  321. },
  322. // 选中时间
  323. selectedDates(e) {
  324. if (e) {
  325. this.search_data.start_time = e[0];
  326. this.search_data.end_time = e[1];
  327. } else {
  328. this.search_data.start_time = '';
  329. this.search_data.end_time = '';
  330. this.dates = null;
  331. }
  332. },
  333. pagination(currentPage) {
  334. let self = this;
  335. self.page = currentPage;
  336. self.getList();
  337. },
  338. getDetail(id,type)
  339. {
  340. let self = this;
  341. request({
  342. params: {
  343. r: 'happiness/store-voucher-order/detail',
  344. id: id,
  345. },
  346. method: 'get',
  347. }).then(e => {
  348. if(e.data.code === 0)
  349. {
  350. self.detail=e.data.data;
  351. if(type=='send')
  352. {
  353. self.sendForm.goods=[]
  354. for(let i in e.data.data.goods)
  355. {
  356. if(e.data.data.goods[i].leave_num>0)
  357. {
  358. self.sendForm.goods.push({
  359. goods_id:e.data.data.goods[i].goods_id,
  360. goods_name:e.data.data.goods[i].goods_name,
  361. goods_attr_name:e.data.data.goods[i].goods_attr_name,
  362. leave_num:e.data.data.goods[i].leave_num,
  363. attr_id:e.data.data.goods[i].attr_id,
  364. send_num:0,
  365. create_date:'',
  366. expire_date:'',
  367. save_day:'',
  368. id:e.data.data.goods[i].id,
  369. cover_pic:e.data.data.goods[i].cover_pic,
  370. })
  371. }
  372. }
  373. }
  374. if(type=='audit')
  375. {
  376. self.auditForm.goods=e.data.data.goods;
  377. }
  378. }
  379. else
  380. {
  381. self.$message.error(e.data.msg);
  382. }
  383. }).catch(e => {
  384. });
  385. },
  386. express(row)
  387. {
  388. this.dialogExpressVisible=true;
  389. let self = this;
  390. let basic_params = {
  391. r: 'happiness/store-voucher-order/express',
  392. id:row.id
  393. };
  394. request({
  395. params: basic_params,
  396. method: 'get',
  397. }).then(e => {
  398. self.listLoading = false;
  399. if (e.data.code === 0) {
  400. self.express_list = e.data.data;
  401. } else {
  402. self.$message.error(e.data.msg);
  403. }
  404. }).catch(e => {
  405. });
  406. },
  407. audit(row)
  408. {
  409. this.auditForm.id=row.id;
  410. this.getDetail(row.id,'audit');
  411. this.dialogVisible=true;
  412. },
  413. send(row)
  414. {
  415. this.sendForm.id=row.id;
  416. this.getDetail(row.id,'send');
  417. this.dialogSendVisible=true;
  418. },
  419. showGoods(row)
  420. {
  421. this.sendForm.id=row.id;
  422. this.getDetail(row.id,'goods');
  423. this.dialogGoodsVisible=true;
  424. },
  425. getList(id) {
  426. let self = this;
  427. let basic_params = {
  428. r: 'happiness/store-voucher-order/index',
  429. page: self.page,
  430. };
  431. params = Object.assign(basic_params, this.search_data);
  432. if (self.listLoading === false) {
  433. self.listLoading = true;
  434. request({
  435. params: params,
  436. method: 'get',
  437. }).then(e => {
  438. self.listLoading = false;
  439. if (e.data.code === 0) {
  440. self.list = e.data.data.list;
  441. self.pageCount = e.data.data.page_count;
  442. } else {
  443. self.$message.error(e.data.msg);
  444. }
  445. }).catch(e => {
  446. });
  447. }
  448. },
  449. search() {
  450. this.page = 1;
  451. this.getList();
  452. },
  453. clearSearch() {
  454. this.search_data.store_keyword = null;
  455. this.search_data.start_time = null;
  456. this.search_data.end_time = null;
  457. this.dates = null;
  458. this.getList();
  459. },
  460. handle(type, data = null) {
  461. let id = data ? parseInt(data.id) : '';
  462. let user_id = data ? parseInt(data.user_id) : '';
  463. switch (type) {
  464. case 'audit':
  465. //确认提示
  466. this.btnLoading=true;
  467. this.$request({
  468. params: {
  469. r: 'happiness/store-voucher-order/switch-status'
  470. },
  471. data:this.auditForm,
  472. method: 'post',
  473. }).then(e => {
  474. if (e.data.code === 0) {
  475. if(this.auditForm.status==1)
  476. {
  477. this.$message.success('审核通过');
  478. }
  479. else
  480. {
  481. this.$message.success('已拒绝');
  482. }
  483. this.getList();
  484. this.btnLoading=false;
  485. this.dialogVisible=false;
  486. } else {
  487. this.$message.error(e.data.msg);
  488. this.btnLoading=false;
  489. }
  490. }).catch(e => {
  491. });
  492. break;
  493. case 'send':
  494. //确认提示
  495. this.btnLoading=true;
  496. this.$request({
  497. params: {
  498. r: 'happiness/store-voucher-order/send'
  499. },
  500. data:this.sendForm,
  501. method: 'post',
  502. }).then(e => {
  503. if (e.data.code === 0) {
  504. this.$message.success('发货成功');
  505. this.getList();
  506. this.btnLoading=false;
  507. this.dialogSendVisible=false;
  508. } else {
  509. this.$message.error(e.data.msg);
  510. this.btnLoading=false;
  511. }
  512. }).catch(e => {
  513. });
  514. break;
  515. }
  516. },
  517. }
  518. })
  519. </script>
  520. <style>
  521. .flex {
  522. display: flex;
  523. align-items: center;
  524. }
  525. .stat_details{
  526. padding: 0 0 20px;
  527. display: flex;
  528. }
  529. .stat_details .order_module{
  530. flex: 1;
  531. background: #F2F2F2;
  532. margin: 0 5px;
  533. padding: 20px 25px;
  534. }
  535. .order_module{
  536. display: flex;
  537. flex-direction: column;
  538. }
  539. .order_module:last-child{
  540. margin-right: 0;
  541. }
  542. .order_module:first-child{
  543. margin-left: 0;
  544. }
  545. .price{
  546. font-size: 14px;
  547. flex: 1;
  548. word-break: break-all;
  549. }
  550. .oirder_modul_title{
  551. font-size: 12px;
  552. margin-bottom: 10px;
  553. display: flex;
  554. align-items: center;
  555. }
  556. ..el-input__inner{
  557. border-right: 1px solid #EBEEF5;
  558. }
  559. .oirder_modul_title .text{
  560. margin-right: 10px;
  561. }
  562. .stat_icon{
  563. font-size: 19px;
  564. color: #BFBFBF;
  565. }
  566. </style>