addOrder.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. <template>
  2. <div class="app-container">
  3. <!-- 添加一个加载状态,在获取createOrderType之前显示 -->
  4. <div v-if="!formReady" style="text-align: center; padding: 50px;">
  5. <i class="el-icon-loading"></i> 正在加载...
  6. </div>
  7. <!-- 只有在formReady为true时才显示表单 -->
  8. <el-form v-if="formReady" ref="form" :model="form" :rules="rules" label-width="120px">
  9. <el-form-item label="会员信息" prop="userId">
  10. <el-table border style="margin-top:5px;" v-loading="userloading" :data="users">
  11. <el-table-column label="ID" align="center" prop="userId" />
  12. <el-table-column label="会员头像" align="center" width="80">
  13. <template slot-scope="scope">
  14. <el-popover placement="right" title="" trigger="hover">
  15. <img slot="reference" :src="scope.row.avatar" width="50">
  16. <img :src="scope.row.avatar" style="max-width: 120px;">
  17. </el-popover>
  18. </template>
  19. </el-table-column>
  20. <el-table-column label="昵称" align="center" prop="nickname" />
  21. <el-table-column label="手机号" align="center" prop="phone" />
  22. <el-table-column label="状态" align="center" prop="status">
  23. <template slot-scope="scope">
  24. <el-tag prop="status" v-for="(item, index) in userStatusOptions" v-if="scope.row.status==item.dictValue">{{item.dictLabel}}</el-tag>
  25. </template>
  26. </el-table-column>
  27. </el-table>
  28. </el-form-item>
  29. <el-form-item label="收货信息" prop="addressId">
  30. <el-row>
  31. <el-col>
  32. <el-button plain type="primary" icon="el-icon-plus" @click="handleAddUserAddress()">添加收货地址</el-button>
  33. </el-col>
  34. </el-row>
  35. <el-radio-group v-model="form.addressId" style="width:100%">
  36. <el-table border style="margin-top:5px;" v-loading="addressloading" :data="address">
  37. <el-table-column label="ID" align="center" >
  38. <template slot-scope="scope">
  39. <el-radio :label="scope.row.addressId"></el-radio>
  40. </template>
  41. </el-table-column>
  42. <el-table-column label="收货人姓名" align="center" prop="realName" />
  43. <el-table-column label="收货人电话" align="center" prop="phone" />
  44. <el-table-column label="地址" align="center" prop="detail">
  45. <template slot-scope="scope">
  46. {{scope.row.province}} {{scope.row.city}} {{scope.row.district}} {{scope.row.detail}}
  47. </template>
  48. </el-table-column>
  49. </el-table>
  50. </el-radio-group>
  51. </el-form-item>
  52. <el-form-item label="商品列表">
  53. <el-row>
  54. <el-col>
  55. <el-button plain type="primary" icon="el-icon-plus" @click="handleAddProduct">添加商品</el-button>
  56. </el-col>
  57. </el-row>
  58. <el-table border :key="tablekey" width="100%" style="margin-top:5px;" :data="products">
  59. <el-table-column label="商品名称" align="center" prop="goodsName" />
  60. <el-table-column label="商品图片" align="center" width="100">
  61. <template slot-scope="scope">
  62. <el-popover placement="right" title="" trigger="hover">
  63. <img slot="reference" :src="scope.row.imgUrl" width="50">
  64. <img :src="scope.row.imgUrl" style="max-width: 50px;">
  65. </el-popover>
  66. </template>
  67. </el-table-column>
  68. <el-table-column label="库存" align="center" prop="stock" />
  69. <el-table-column label="所需积分" align="center" prop="integral" />
  70. <el-table-column label="需支付金额" align="center" prop="cash" />
  71. <el-table-column label="商品编号" align="center" prop="barCode" />
  72. <el-table-column label="操作" align="center" width="100px">
  73. <template slot-scope="scope">
  74. <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
  75. </template>
  76. </el-table-column>
  77. </el-table>
  78. </el-form-item>
  79. <el-form-item label="订单备注" prop="mark">
  80. <el-input type="textarea" rows="2" v-model="form.mark" placeholder="" />
  81. </el-form-item>
  82. </el-form>
  83. <div v-if="formReady" slot="footer" class="dialog-footer" style="float: right; margin-bottom: 20px;">
  84. <el-button type="primary" @click="submitForm">确 定</el-button>
  85. <el-button @click="cancel">取 消</el-button>
  86. </div>
  87. <!-- 对话框部分保持不变 -->
  88. <el-dialog :title="product.title" v-if="product.open" :visible.sync="product.open" width="1000px" append-to-body>
  89. <product-select @selectProduct="selectProduct" />
  90. </el-dialog>
  91. <el-dialog :title="user.title" v-if="user.open" :visible.sync="user.open" width="500px" append-to-body>
  92. <add-user @addUser="addUser" />
  93. </el-dialog>
  94. <el-dialog :title="userAddress.title" v-if="userAddress.open" :visible.sync="userAddress.open" width="800px" append-to-body>
  95. <add-user-address ref="addUserAddress" @addUserAddress="addUserAddress" />
  96. </el-dialog>
  97. <el-dialog :title="payQr.title" v-if="payQr.open" :visible.sync="payQr.open" width="240px" append-to-body>
  98. <div style="padding-bottom:15px;">
  99. <div class="qrcode" ref="qrCodeUrl"></div>
  100. </div>
  101. </el-dialog>
  102. </div>
  103. </template>
  104. <script>
  105. import { addIntegralOrder } from "@/api/hisStore/integralOrder";
  106. import { getUserList } from "@/api/users/user";
  107. import { getAddressList } from "@/api/users/userAddress";
  108. import { getTcmScheduleList } from "@/api/company/tcmScheduleReport";
  109. import productSelect from "@/views/hisStore/integralOrder/integralProductSelect";
  110. import addUserAddress from "@/views/hisStore/components/addUserAddress";
  111. import config from "@/utils/config";
  112. import QRCode from 'qrcodejs2'
  113. import { treeselect } from "@/api/company/companyDept";
  114. import Treeselect from "@riophae/vue-treeselect";
  115. import "@riophae/vue-treeselect/dist/vue-treeselect.css";
  116. export default {
  117. components: { Treeselect,productSelect,addUserAddress },
  118. name: "StoreOrder",
  119. props: {
  120. customerId: {
  121. type: Number,
  122. required: false
  123. },
  124. userId: {
  125. type: Number,
  126. required: false
  127. }
  128. },
  129. data() {
  130. return {
  131. // 添加表单准备状态
  132. formReady: false,
  133. createOrderType: null,
  134. // 部门树选项
  135. deptOptions: undefined,
  136. // 部门名称
  137. deptName: undefined,
  138. defaultProps: {
  139. children: "children",
  140. label: "label",
  141. },
  142. deliveryPayStatusOptions:[],
  143. deliveryStatusOptions:[],
  144. dateRange: [],
  145. orderTypeOptions:[],
  146. orderMediumOptions:[],
  147. payTypeOptions:[],
  148. payQr:{
  149. open:false,
  150. title:"付款二维码"
  151. },
  152. user:{
  153. open:false,
  154. title:"创建会员"
  155. },
  156. userAddress:{
  157. open:false,
  158. title:"创建收货地址"
  159. },
  160. tablekey:false,
  161. totalMoney:0.00,
  162. products:[],
  163. product:{
  164. open:false,
  165. title:"商品选择"
  166. },
  167. phone:null,
  168. address:[],
  169. addressloading: false,
  170. userloading: false,
  171. users:[],
  172. userStatusOptions:[],
  173. show:{
  174. open:false,
  175. title:"订单详情"
  176. },
  177. activeName:"00",
  178. statusOptions:[],
  179. // 遮罩层
  180. loading: true,
  181. // 选中数组
  182. ids: [],
  183. // 非单个禁用
  184. single: true,
  185. // 非多个禁用
  186. multiple: true,
  187. // 显示搜索条件
  188. showSearch: true,
  189. // 总条数
  190. total: 0,
  191. // 订单表格数据
  192. storeOrderList: [],
  193. // 弹出层标题
  194. title: "",
  195. // 是否显示弹出层
  196. open: false,
  197. createTimeRange:[],
  198. payTimeRange:[],
  199. deliveryImportTimeRange:[],
  200. scheduleOptions:[],
  201. // 查询参数
  202. queryParams: {
  203. pageNum: 1,
  204. pageSize: 10,
  205. orderCode: null,
  206. extendOrderId: null,
  207. userId: null,
  208. realName: null,
  209. userPhone: null,
  210. userAddress: null,
  211. cartId: null,
  212. freightPrice: null,
  213. totalNum: null,
  214. totalPrice: null,
  215. totalPostage: null,
  216. payPrice: null,
  217. payPostage: null,
  218. deductionPrice: null,
  219. couponId: null,
  220. couponPrice: null,
  221. paid: null,
  222. payTime: null,
  223. payType: null,
  224. status: null,
  225. refundStatus: null,
  226. refundReasonWapImg: null,
  227. refundReasonWapExplain: null,
  228. refundReasonTime: null,
  229. refundReasonWap: null,
  230. refundReason: null,
  231. refundPrice: null,
  232. deliverySn: null,
  233. deliveryName: null,
  234. deliveryType: null,
  235. deliveryId: null,
  236. gainIntegral: null,
  237. useIntegral: null,
  238. payIntegral: null,
  239. backIntegral: null,
  240. mark: null,
  241. isDel: null,
  242. cost: null,
  243. verifyCode: null,
  244. storeId: null,
  245. shippingType: null,
  246. isChannel: null,
  247. isRemind: null,
  248. isSysDel: null
  249. },
  250. // 表单参数
  251. form: {
  252. addressId:null,
  253. userId:null,
  254. products:[],
  255. },
  256. // 表单校验
  257. rules: {
  258. userId: [
  259. { required: true, message: "会员信息不能为空", trigger: "submit" }
  260. ],
  261. addressId: [
  262. { required: true, message: "收货信息不能为空", trigger: "submit" }
  263. ],
  264. products: [
  265. { required: true, message: "商品不能为空", trigger: "submit" }
  266. ],
  267. }
  268. };
  269. },
  270. watch: {
  271. // 根据名称筛选部门树
  272. deptName(val) {
  273. this.$refs.tree.filter(val);
  274. },
  275. },
  276. created() {
  277. // 先获取createOrderType,然后再初始化其他数据
  278. this.initializeForm();
  279. },
  280. methods: {
  281. // 初始化表单的方法
  282. async initializeForm() {
  283. try {
  284. // 2. 然后并行加载其他数据
  285. await Promise.all([
  286. this.loadDictionaries(),
  287. this.loadOtherData(),
  288. this.initUser()
  289. ]);
  290. // 3. 所有数据加载完成后,设置表单为准备状态
  291. this.formReady = true;
  292. console.log('Form is ready to display');
  293. } catch (error) {
  294. console.error('Error initializing form:', error);
  295. this.$message.error('表单初始化失败');
  296. }
  297. },
  298. // 加载字典数据
  299. async loadDictionaries() {
  300. const dictPromises = [
  301. this.getDicts("crm_customer_source").then((response) => {
  302. this.orderMediumOptions = response.data;
  303. }),
  304. this.getDicts("store_order_type").then((response) => {
  305. this.orderTypeOptions = response.data;
  306. }),
  307. this.getDicts("store_pay_type").then((response) => {
  308. this.payTypeOptions = response.data;
  309. }),
  310. this.getDicts("user_status").then((response) => {
  311. this.userStatusOptions = response.data;
  312. }),
  313. this.getDicts("store_order_status").then((response) => {
  314. this.statusOptions = response.data;
  315. }),
  316. this.getDicts("store_order_delivery_status").then((response) => {
  317. this.deliveryStatusOptions = response.data;
  318. }),
  319. this.getDicts("store_delivery_pay_status").then((response) => {
  320. this.deliveryPayStatusOptions = response.data;
  321. })
  322. ];
  323. await Promise.all(dictPromises);
  324. },
  325. // 加载其他数据
  326. async loadOtherData() {
  327. await Promise.all([
  328. this.getTreeselect(),
  329. getTcmScheduleList().then(response => {
  330. this.scheduleOptions = response.data;
  331. })
  332. ]);
  333. },
  334. initUser(){
  335. return new Promise((resolve) => {
  336. if(this.userId != null){
  337. var data={userId:this.userId}
  338. this.userloading = true;
  339. this.users=[];
  340. this.address=[];
  341. getUserList(data).then(response => {
  342. this.users = response.data;
  343. this.userloading = false;
  344. if(this.users!=null&&this.users.length==1){
  345. this.form.userId=this.users[0].userId;
  346. this.getAddressList(this.form.userId).then(() => {
  347. resolve();
  348. });
  349. } else {
  350. resolve();
  351. }
  352. }).catch(() => {
  353. resolve();
  354. });
  355. } else {
  356. resolve();
  357. }
  358. });
  359. },
  360. /** 查询部门下拉树结构 */
  361. getTreeselect() {
  362. return treeselect().then((response) => {
  363. this.deptOptions = response.data;
  364. });
  365. },
  366. // 修改getAddressList方法,返回Promise
  367. getAddressList(userId){
  368. var data={userId:userId}
  369. this.addressloading = true;
  370. this.address=[];
  371. return getAddressList(data).then(response => {
  372. this.address = response.data;
  373. this.addressloading = false;
  374. });
  375. },
  376. // 其他方法保持不变...
  377. // 筛选节点
  378. filterNode(value, data) {
  379. if (!value) return true;
  380. return data.label.indexOf(value) !== -1;
  381. },
  382. // 节点单击事件
  383. handleNodeClick(data) {
  384. this.queryParams.deptId = data.id;
  385. this.getList();
  386. },
  387. handleGenPayUrl(row){
  388. this.payQr.open=true;
  389. setTimeout(() => {
  390. var qrcode = new QRCode(this.$refs.qrCodeUrl, {
  391. text: config.payQRUrl+row.id,
  392. width: 200,
  393. height: 200,
  394. colorDark: '#000000',
  395. colorLight: '#ffffff',
  396. correctLevel: QRCode.CorrectLevel.H
  397. })
  398. }, 200);
  399. },
  400. handleAddUser(){
  401. this.user.open=true;
  402. },
  403. handleAddUserAddress(){
  404. this.userAddress.open=true;
  405. setTimeout(() => {
  406. this.$refs.addUserAddress.init(this.form.userId);
  407. }, 500);
  408. },
  409. addUserAddress(){
  410. this.userAddress.open=false;
  411. //获取地址
  412. this.getAddressList(this.form.userId);
  413. },
  414. addUser(){
  415. this.user.open=false;
  416. },
  417. compute(){
  418. this.totalMoney=0;
  419. var that=this;
  420. this.products.forEach (function (value) {
  421. that.totalMoney += value.money;
  422. });
  423. },
  424. handleProductCountChange(row){
  425. this.tablekey = !this.tablekey
  426. row.money=row.count*row.price;
  427. this.$forceUpdate();
  428. this.compute();
  429. },
  430. selectProduct(row){
  431. for(var i=0;i<this.products.length;i++){
  432. if(this.products[i].id==row.id){
  433. this.$message.warning("请删除商品在重新选择!")
  434. return;
  435. }
  436. }
  437. row.count=1;
  438. row.money=row.count*row.price;
  439. this.products.push(row);
  440. this.$message.success("商品"+ row.goodsName + "添加成功")
  441. this.compute();
  442. this.product.open=false;
  443. },
  444. handleAddProduct(){
  445. this.product.open=true;
  446. },
  447. searchUser(){
  448. if(this.phone==null||this.phone==""){
  449. return;
  450. }
  451. var data={phone:this.phone}
  452. this.userloading = true;
  453. this.users=[];
  454. this.address=[];
  455. getUserList(data).then(response => {
  456. this.users = response.data;
  457. this.userloading = false;
  458. if(this.users!=null&&this.users.length==1){
  459. this.form.userId=this.users[0].userId;
  460. this.getAddressList(this.form.userId)
  461. }
  462. });
  463. },
  464. handleDetails(row){
  465. this.show.open=true;
  466. const orderId = row.id ;
  467. setTimeout(() => {
  468. this.$refs.order.getOrder(orderId);
  469. }, 500);
  470. },
  471. handleClick(tab, event) {
  472. if(tab.name=="all"){
  473. this.queryParams.status==null;
  474. }
  475. else{
  476. this.queryParams.status=tab.name;
  477. }
  478. this.getList();
  479. },
  480. /** 查询订单列表 */
  481. getList() {
  482. if(this.queryParams.status=='00'){
  483. this.queryParams.status=null;
  484. }
  485. if(this.createTimeRange!=null&&this.createTimeRange.length==2){
  486. this.queryParams.createTimeRange=this.createTimeRange[0]+"--"+this.createTimeRange[1]
  487. }
  488. else{
  489. this.queryParams.createTimeRange=null;
  490. }
  491. if(this.payTimeRange!=null&&this.payTimeRange.length==2){
  492. this.queryParams.payTimeRange=this.payTimeRange[0]+"--"+this.payTimeRange[1]
  493. }
  494. else{
  495. this.queryParams.payTimeRange=null;
  496. }
  497. if(this.deliveryImportTimeRange!=null&&this.deliveryImportTimeRange.length==2){
  498. this.queryParams.deliveryImportTimeRange=this.deliveryImportTimeRange[0]+"--"+this.deliveryImportTimeRange[1]
  499. }
  500. else{
  501. this.queryParams.deliveryImportTimeRange=null;
  502. }
  503. this.loading = true;
  504. },
  505. // 取消按钮
  506. cancel() {
  507. this.open = false;
  508. this.reset();
  509. this.$emit("closePackage")
  510. },
  511. // 表单重置
  512. reset() {
  513. this.form = {
  514. addressId:null,
  515. userId:null,
  516. products:null,
  517. };
  518. this.resetForm("form");
  519. },
  520. /** 搜索按钮操作 */
  521. handleQuery() {
  522. this.queryParams.pageNum = 1;
  523. this.getList();
  524. },
  525. /** 重置按钮操作 */
  526. resetQuery() {
  527. this.resetForm("queryForm");
  528. this.handleQuery();
  529. },
  530. /** 新增按钮操作 */
  531. handleAdd() {
  532. this.reset();
  533. this.open = true;
  534. this.title = "创建订单";
  535. },
  536. /** 提交按钮 */
  537. submitForm() {
  538. this.$refs["form"].validate(valid => {
  539. if(this.products.length==0){
  540. this.msgError("请选择商品");
  541. return;
  542. }
  543. this.form.products=this.products;
  544. if (valid) {
  545. this.form.goodsId = this.form.products[0].goodsId;
  546. // console.log("this.form:{}",this.form.products[0].goodsId)
  547. addIntegralOrder(this.form).then(response => {
  548. if (response.code === 200) {
  549. this.msgSuccess("创建成功");
  550. this.$emit("closePackage")
  551. }
  552. });
  553. }
  554. });
  555. },
  556. /** 删除按钮操作 */
  557. handleDelete(row) {
  558. this.products.splice(this.products.findIndex(item => item.id === row.id), 1)
  559. this.compute();
  560. },
  561. }
  562. };
  563. </script>
  564. <style scoped lang="scss">
  565. .items{
  566. margin: 5px 0px;
  567. display: flex;
  568. flex-direction: row;
  569. align-items: center;
  570. justify-content: flex-start;
  571. .pic{
  572. width:60px;
  573. height:60px;
  574. }
  575. .goods-content{
  576. margin-left: 10px;
  577. max-width: 200px;
  578. text-align: left;
  579. .goods-title{
  580. overflow:hidden;
  581. white-space: nowrap;
  582. text-overflow: ellipsis;
  583. -o-text-overflow:ellipsis;
  584. }
  585. }
  586. }
  587. .el-message-box__message p{
  588. max-height: 400px;
  589. overflow:scroll;
  590. }
  591. .import-msg{
  592. height: 500px;
  593. overflow: auto;
  594. }
  595. </style>
  596. <style>
  597. .el-descriptions-item__label.is-bordered-label{
  598. font-weight: normal;
  599. }
  600. </style>