order-shipping.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <?php
  2. use common\helpers\ComponentHelper;
  3. if (isset($is_electronic_bill) && $is_electronic_bill) {
  4. ComponentHelper::loadComponentView('electronic-bill', \Yii::$app->basePath . '/../addons/' . \common\enums\AddonsEnum::ADDONS_NAME_ELECTRONIC_BILL . '/common/components/order');
  5. }
  6. ?>
  7. <template id="order-shipping">
  8. <div>
  9. <el-dialog title="基本信息" :visible.sync="isShowChangeShipping" @close="dialogClose" :close-on-click-modal="false">
  10. <el-form :model="form" ref="ships" :rules="rules" label-width="80px" size="small" label-position="top" style="padding: 0 30px;">
  11. <el-form-item label="">
  12. <el-table ref="multipleTable" :data="details_list" size="small" border style="width: 100%" @selection-change="handleSelectionChange">
  13. <el-table-column type="selection" width="55" :selectable="selectable"></el-table-column>
  14. <el-table-column label="商品" width="200" prop="goods_name">
  15. <template slot-scope="scope">
  16. <com-ellipsis :line="1" :text="scope.row.goods_name"></com-ellipsis>
  17. </template>
  18. </el-table-column>
  19. <el-table-column prop="num" label="数量" width="120">
  20. </el-table-column>
  21. <el-table-column prop="unshipped_num" label="待发货数量" width="120">
  22. </el-table-column>
  23. <el-table-column prop="num" label="发货数量" width="120">
  24. <template slot-scope="scope">
  25. <el-input v-model="scope.row.send_num" :min="0" :max="scope.row.unshipped_num"></el-input>
  26. </template>
  27. </el-table-column>
  28. <el-table-column prop="is_feedback" label="售后状态" show-overflow-tooltip>
  29. <template slot-scope="scope">
  30. <el-tag v-if="scope.row.is_feedback == 1" type="danger" size="small" effect="plain">售后中</el-tag>
  31. <el-tag v-if="scope.row.is_feedback == 2" type="danger" size="small" effect="plain">售后完成</el-tag>
  32. </template>
  33. </el-table-column>
  34. <el-table-column prop="num" label="状态" show-overflow-tooltip>
  35. <template slot-scope="scope">{{ scope.row.shipping_status == 1 ? '已发货' : '待发货' }}</template>
  36. </el-table-column>
  37. </el-table>
  38. <div style="margin-top: 10px; display: flex; justify-content: flex-end">
  39. <el-pagination
  40. background
  41. @current-change="handleCurrentChange"
  42. :current-page.sync="currentPage"
  43. :page-size="pageSize"
  44. layout="total, prev, pager, next"
  45. :total="detailsTotal">
  46. </el-pagination>
  47. </div>
  48. </el-form-item>
  49. <div class="title-box" style="margin: 15px 0;">
  50. <span class="text" style="background-color: #FEFAEF;color: #E6A23C;padding: 6px;margin-right: 10px;">物流信息</span>
  51. <span style="color: red;">*注:物流修改仅支持修改一次</span>
  52. </div>
  53. <el-form-item label="发货方式">
  54. <el-radio-group v-model="form.shipping_type">
  55. <el-radio :label="1" :disabled="isNeedNotExpress">快递</el-radio>
  56. <el-radio :label="0">无需物流</el-radio>
  57. <?php if (isset($is_electronic_bill) && $is_electronic_bill) { ?>
  58. <el-radio :label="2" :disabled="isNeedNotExpress">电子面单</el-radio>
  59. <?php } ?>
  60. </el-radio-group>
  61. </el-form-item>
  62. <div v-if="form.shipping_type == 1">
  63. <el-form-item label="快递公司" prop="company">
  64. <el-select style="width:30%" filterable v-model="form.express_id" placeholder="请选择快递公司" style="width: 100%" @change="handleExpressChange">
  65. <el-option v-for="company in express_companys" :key="company.id" :label="company.name" :value="company.id">
  66. </el-option>
  67. </el-select>
  68. </el-form-item>
  69. <!--<el-form-item label="商家编码" prop="customer_name"
  70. v-if="form.shipping_type == 1 && (form.express_name === '京东物流' || form.express_name === '京东快运')">
  71. <el-input style="width:50%" placeholder="请输入商家编码" size="small" v-model="form.customer_name"
  72. autocomplete="off"></el-input>
  73. </el-form-item>-->
  74. <el-form-item label="快递单号" prop="express_no">
  75. <el-input style="width:50%" v-model="form.express_no"></el-input>
  76. </el-form-item>
  77. <!-- <el-form-item label="商家备注" prop="memo">
  78. <el-input style="width:50%" type="textarea" v-model="form.memo"></el-input>
  79. </el-form-item> -->
  80. <el-form-item label="商家备注1" prop="memo_arr1">
  81. <el-input style="width:50%" type="textarea" v-model="form.memo_arr1"></el-input>
  82. </el-form-item>
  83. <el-form-item label="商家备注2" prop="memo_arr2">
  84. <el-input style="width:50%" type="textarea" v-model="form.memo_arr2"></el-input>
  85. </el-form-item>
  86. <el-form-item label="商家备注3" prop="memo_arr3">
  87. <el-input style="width:50%" type="textarea" v-model="form.memo_arr3"></el-input>
  88. </el-form-item>
  89. <el-form-item>
  90. <div>收货信息:</div>
  91. <div style="line-height: 22px;">收货人:{{ order_info.receiver_name }}</div>
  92. <div style="line-height: 22px;">联系电话:{{ order_info.mobile }}</div>
  93. <div style="line-height: 22px;">收货地址: {{order_info.region_name}} {{order_info.address}}</div>
  94. </el-form-item>
  95. <el-form-item v-if="order_info.pickup_info">
  96. <div>自提点信息:</div>
  97. <div style="line-height: 22px;">收货人:{{ order_info.pickup_info.head_info.contact_name }}</div>
  98. <div style="line-height: 22px;">联系电话:{{ order_info.pickup_info.head_info.contact_phone }}</div>
  99. <div style="line-height: 22px;">收货地址:{{order_info.pickup_info.head_info.address}}</div>
  100. </el-form-item>
  101. </div>
  102. <div v-if="form.shipping_type == 0">
  103. <el-form-item label="商家备注1" prop="memo_arr1">
  104. <el-input style="width:50%" type="textarea" v-model="form.memo_arr1"></el-input>
  105. </el-form-item>
  106. <el-form-item label="商家备注2" prop="memo_arr2">
  107. <el-input style="width:50%" type="textarea" v-model="form.memo_arr2"></el-input>
  108. </el-form-item>
  109. <el-form-item label="商家备注3" prop="memo_arr3">
  110. <el-input style="width:50%" type="textarea" v-model="form.memo_arr3"></el-input>
  111. </el-form-item>
  112. </div>
  113. <?php if (isset($is_electronic_bill) && $is_electronic_bill) { ?>
  114. <electronic-bill v-if="form.shipping_type == 2" :parent-show="is_show" :parent-form="form" @update-form="form = $event" @change-comfirm="comfirm = $event(_self, 'ships')"></electronic-bill>
  115. <?php } ?>
  116. </el-form>
  117. <div slot="footer" class="dialog-footer">
  118. <el-button @click="isShowChangeShipping = false">取 消</el-button>
  119. <el-button type="primary" @click="comfirm('ships')" :v-loading="changeShippingLoading">确 定</el-button>
  120. </div>
  121. </el-dialog>
  122. </div>
  123. </template>
  124. <script>
  125. function paginate(array, page_size, page_number) {
  126. // 计算分页开始的索引
  127. const start = (page_number - 1) * page_size;
  128. // 计算分页结束的索引
  129. const end = page_number * page_size;
  130. // 返回分页后的数组
  131. return array.slice(start, end);
  132. }
  133. Vue.component('order-shipping', {
  134. template: '#order-shipping',
  135. props: {
  136. is_show: {
  137. type: Boolean,
  138. default: false
  139. },
  140. order_info: {
  141. type: Object,
  142. default: function() {
  143. return {};
  144. }
  145. },
  146. changeShippingLoading:{
  147. type:Boolean,
  148. default:false
  149. },
  150. shipping_form: {
  151. type: Object,
  152. default: function() {
  153. return {};
  154. }
  155. }
  156. },
  157. data() {
  158. return {
  159. express_companys: [],
  160. form: {
  161. id:'',
  162. order_detail_ids:[],// 选中的发货商品
  163. send_nums:[],// 发货数量
  164. shipping_type: 1, // 发货方式 [1快递 0无需物流]
  165. express_id: '', // 快递公司
  166. express_name:'', // 快递名称
  167. customer_name:'', // 京东物流编号
  168. express_no: '', // 快递单号
  169. memo_arr1: '', //卖家备注
  170. memo_arr2: '', //卖家备注
  171. memo_arr3: '', //卖家备注
  172. },
  173. isShowChangeShipping: false,
  174. isNeedNotExpress: false, // 判断是否无需物流信息
  175. order_status_list: {
  176. '0': "待付款",
  177. '1': "待发货",
  178. '2': "已发货",
  179. '3': "已收货",
  180. '4': "已完成",
  181. '-1': "售后申请",
  182. '-2': "退款中",
  183. '-3': "售后完成",
  184. '-4': "已关闭",
  185. },
  186. rules: {
  187. express_id: [{
  188. required: true,
  189. message: '请选择快递公司',
  190. trigger: 'change'
  191. }],
  192. express_no: [{
  193. required: true,
  194. message: '请填写快递单号',
  195. trigger: 'change'
  196. }],
  197. customer_name: [{
  198. required: true,
  199. message: '请填写商家编码',
  200. trigger: 'change'
  201. }]
  202. },
  203. currentPage: 1,
  204. pageSize: 10,
  205. detailsTotal: 0,
  206. details_list: [], // 用于分页
  207. }
  208. },
  209. watch: {
  210. is_show: function(newVal) {
  211. if(newVal){
  212. // 获取订单物流信息列表
  213. this.$nextTick(()=>{
  214. this.$refs.multipleTable.toggleAllSelection(true);
  215. })
  216. if(isEmpty(this.express_companys)) this.getOrderShipping()
  217. }
  218. this.isShowChangeShipping = newVal;
  219. if (!this.shipping_form.order_no && Object.keys(this.shipping_form).length > 1) {
  220. this.shipping_form.shipping_change = 1;// 修改物流
  221. this.form = this.shipping_form;
  222. } else {
  223. this.form.express_id = ''; // 快递公司
  224. this.form.express_name = ''; // 快递名称
  225. this.form.customer_name = ''; // 京东物流编号
  226. this.form.express_no = ''; // 快递单号
  227. this.form.memo = ''; //卖家备注
  228. }
  229. },
  230. order_info(val) {
  231. // // console.log(val, 'val')
  232. this.form.id = val.id
  233. // 判断是否无需物流
  234. // this.form.detail = val.detail
  235. // this.form.region_name = val.region_name
  236. // this.form.address = val.address
  237. this.form.shipping_type = Number(this.form.shipping_type)
  238. if (val && typeof val.need_not_express !== 'undefined') {
  239. this.isNeedNotExpress = Boolean(val.need_not_express);
  240. if (this.isNeedNotExpress) {
  241. this.form.shipping_type = 0;
  242. }
  243. }
  244. if (this.order_info?.detail) {
  245. this.detailsTotal = this.order_info.detail.length
  246. for (const item of this.order_info.detail) {
  247. this.$set(item, 'unshipped_num', item.num - item.shipped_num)
  248. this.$set(item, 'send_num', item.unshipped_num)
  249. }
  250. this.details_list = paginate(this.order_info.detail, this.pageSize, 1)
  251. }
  252. }
  253. },
  254. methods: {
  255. getOrderShipping(){
  256. request({
  257. params: {
  258. r: 'mall/order/shipping'
  259. },
  260. }).then(res => {
  261. if(res.data.code == 0){
  262. this.express_companys = res.data.data.express_list;
  263. this.form.customer_name = res.data.data.jd_mch_code;
  264. }
  265. })
  266. },
  267. selectable(row,index){
  268. if (row.is_feedback != 0) {
  269. return false;
  270. }
  271. return row.shipping_status == 0;
  272. },
  273. handleSelectionChange(e) {
  274. this.form.order_detail_ids = getValues(e,'id');
  275. },
  276. handleExpressChange(e){
  277. let index = this.express_companys.findIndex(v => v.id == e);
  278. this.form.express_name = this.express_companys[index].name;
  279. },
  280. comfirm(formName) {
  281. let res = this.getOrderDetailIds();
  282. if (res.length <= 0) {
  283. this.$message.error('请选择发货商品');
  284. return false;
  285. }
  286. if (this.form.shipping_type == 1 && this.form.express_id <= 0) {
  287. this.$message.error('请选择快递公司');
  288. return false;
  289. }
  290. if (this.form.shipping_type == 1) {
  291. this.$refs[formName].validate((valid) => {
  292. if (valid) {
  293. if (typeof this.form.order_detail_ids == 'string') this.form.order_detail_ids = JSON.parse(this.form.order_detail_ids);
  294. this.setSendNums()
  295. request({
  296. params: {
  297. r: 'mall/order/check-order-express-no',
  298. id: this.form.id,
  299. express_no: this.form.express_no,
  300. },
  301. }).then(res => {
  302. if (res.data?.data?.is_exists === true) {
  303. this.$confirm('此快递单号已经存在,继续操作将合并包裹', '提示', {
  304. confirmButtonText: '确定',
  305. cancelButtonText: '取消',
  306. type: 'warning'
  307. }).then(() => {
  308. this.$emit('submit',this.form);
  309. })
  310. } else {
  311. this.$emit('submit',this.form);
  312. }
  313. })
  314. } else {
  315. console.log('error submit!!');
  316. return;
  317. }
  318. });
  319. } else {
  320. if (typeof this.form.order_detail_ids == 'string') this.form.order_detail_ids = JSON.parse(this.form.order_detail_ids);
  321. this.setSendNums()
  322. this.$emit('submit',this.form);
  323. }
  324. },
  325. setSendNums() {
  326. this.form.send_nums = []
  327. if (this.form?.order_detail_ids && this.order_info?.detail) {
  328. for (const order_detail_id of this.form.order_detail_ids) {
  329. for (const order_info_item of this.order_info.detail) {
  330. if (order_info_item.id == order_detail_id) {
  331. this.form.send_nums.push({id: order_detail_id, num: order_info_item.send_num})
  332. break
  333. }
  334. }
  335. }
  336. }
  337. },
  338. dialogClose() {
  339. this.$emit('close')
  340. },
  341. getOrderDetailIds() {
  342. // 选中的订单商品
  343. let orderDetailIds = [];
  344. Object.keys(this.form.order_detail_ids).forEach(function (item) {
  345. orderDetailIds.push(item.id)
  346. });
  347. return orderDetailIds;
  348. },
  349. handleCurrentChange(value) {
  350. this.details_list = paginate(this.order_info.detail, this.pageSize, value)
  351. },
  352. }
  353. })
  354. </script>