artificial_order.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. <template>
  2. <div>
  3. <el-form ref="form" :model="form" :rules="rules" label-width="80px">
  4. <el-card class="box-card">
  5. <div slot="header" class="header clearfix">
  6. <span>基本信息</span>
  7. </div>
  8. <el-form-item label="订单编号">
  9. <div class="order-number">
  10. <span>{{form.orderNo ? form.orderNo : '未生成'}}</span>
  11. <!-- <span>{{form.orderNo ? `订单编号:${form.orderNo}` : '未生成订单'}}</span>
  12. <span class="order-status" v-if="form.status === '0'">订单创建</span>
  13. <span class="order-status" v-else-if="form.status === '100'">待审核</span>
  14. <span class="order-status" v-else-if="form.status === '101'">审核中</span>
  15. <span class="order-status" v-else-if="form.status === '102'">订单审核成功</span>
  16. <span class="order-status" v-else-if="form.status === '200'">订单开始处理</span>
  17. <span class="order-status" v-else-if="form.status === '201'">订单处理中</span>
  18. <span class="order-status" v-else-if="form.status === '202'">订单已处理</span>
  19. <span class="order-status" v-else-if="form.status === '300'">订单成功</span>
  20. <span class="order-status" v-else-if="form.status === '301'">订单部分退款</span>
  21. <span class="order-status" v-else-if="form.status === '302'">订单已失败</span>
  22. <span class="order-status" v-else-if="form.status === '303'">订单全额退款</span>
  23. <span class="order-status" v-else-if="form.status === '400'">订单支付中</span>
  24. <span class="order-status" v-else-if="form.status === '401'">订单支付成功</span>
  25. <span class="order-status" v-else-if="form.status === '402'">订单支付失败</span>
  26. <span class="order-status" v-else>未生成</span>-->
  27. </div>
  28. </el-form-item>
  29. <el-form-item label="订单用户" prop="uid">
  30. <el-input v-model="form.uid" placeholder="请输入用户uid"></el-input>
  31. </el-form-item>
  32. <el-form-item label="订单名称" prop="productTitle">
  33. <el-input v-model="form.productTitle" placeholder="请输入订单名称,尽量遵循命名规则"></el-input>
  34. </el-form-item>
  35. <el-row :gutter="20">
  36. <el-col :span="12">
  37. <el-form-item label="订单类型" prop="productType">
  38. <el-select
  39. v-model="form.productTypeName"
  40. placeholder="请选择订单类型"
  41. @change="productTypeChange"
  42. >
  43. <el-option
  44. v-for="item in productTypes"
  45. :key="item.id"
  46. :label="item.name"
  47. :value="item.name"
  48. ></el-option>
  49. </el-select>
  50. </el-form-item>
  51. </el-col>
  52. <el-col :span="12">
  53. <el-form-item label="交易类型" prop="orderType">
  54. <el-select
  55. v-model="form.orderTypeName"
  56. placeholder="请选择交易类型"
  57. @change="orderTypeChange"
  58. >
  59. <el-option
  60. v-for="item in orderTypes"
  61. :key="item.id"
  62. :label="item.name"
  63. :value="item.name"
  64. ></el-option>
  65. </el-select>
  66. </el-form-item>
  67. </el-col>
  68. </el-row>
  69. <el-row :gutter="20">
  70. <el-col :span="12">
  71. <el-form-item label="订单金额" prop="price">
  72. <el-input v-model="form.price" placeholder="请输入实际金额"></el-input>
  73. </el-form-item>
  74. </el-col>
  75. <el-col :span="12">
  76. <el-form-item label="变更余额">
  77. <el-radio v-model="radio" label="1" disabled>收入</el-radio>
  78. <el-radio v-model="radio" label="2" disabled>支出</el-radio>
  79. </el-form-item>
  80. </el-col>
  81. </el-row>
  82. <el-row :gutter="20">
  83. <el-col :span="12">
  84. <el-form-item label="收支类型" prop="channel">
  85. <el-select v-model="form.channelName" placeholder="请选择支付方式" @change="channelChange">
  86. <el-option
  87. v-for="item in channels"
  88. :key="item.id"
  89. :label="item.name"
  90. :value="item.name"
  91. ></el-option>
  92. </el-select>
  93. </el-form-item>
  94. </el-col>
  95. <el-col :span="12">
  96. <el-form-item label="支付编码">
  97. <el-input v-model="form.outOrderId" placeholder="请输入支付编号,选填"></el-input>
  98. </el-form-item>
  99. </el-col>
  100. </el-row>
  101. </el-card>
  102. <el-card class="box-card">
  103. <div slot="header" class="header clearfix">
  104. <span>其他信息(选填)</span>
  105. </div>
  106. <el-row :gutter="20">
  107. <el-col :span="12">
  108. <el-form-item label="项目ID" prop="productId">
  109. <el-input v-model.number="form.productId" placeholder="请输入项目ID"></el-input>
  110. </el-form-item>
  111. </el-col>
  112. <el-col :span="12">
  113. <el-form-item label="关联订单" prop="originOrderNo">
  114. <el-input v-model="form.originOrderNo" placeholder="请输入平台订单编号"></el-input>
  115. </el-form-item>
  116. </el-col>
  117. </el-row>
  118. <el-form-item label="外部备注" prop="publicComment">
  119. <el-input v-model="form.publicComment" placeholder="请输入用户可见的备注信息"></el-input>
  120. </el-form-item>
  121. <el-form-item label="内部备注" prop="privateComment">
  122. <quill-editor
  123. :options="editorOption"
  124. v-model="form.privateComment"
  125. ref="myQuillEditor"
  126. class="editer"
  127. ></quill-editor>
  128. <input type="file" hidden accept=".jpg, .png" ref="fileBtn" @change="handleChange" />
  129. </el-form-item>
  130. </el-card>
  131. <el-form-item>
  132. <el-button class="save-btn" type="primary" @click="saveSubmit()">保存</el-button>
  133. <el-button class="cancel-btn" @click="cancelSubmit()">取消</el-button>
  134. </el-form-item>
  135. <el-form-item>
  136. <el-button v-if="hasSave" class="comfirm-btn" type="primary" @click="confirmSubmit()">确认提交订单</el-button>
  137. <el-button v-else class="comfirm-btn" type="info">确认提交订单</el-button>
  138. </el-form-item>
  139. </el-form>
  140. </div>
  141. </template>
  142. <script>
  143. import axios from "axios";
  144. export default {
  145. data() {
  146. let checkPrice = (rule, value, callback) => {
  147. if (!value) {
  148. return callback(new Error("请输入订单金额"));
  149. } else if (isNaN(value) || value > 100000) {
  150. return callback(new Error("请输入实际金额0-10万元"));
  151. } else {
  152. callback();
  153. }
  154. };
  155. let checkProductId = (rule, value, callback) => {
  156. if (isNaN(value)) {
  157. return callback(new Error("请输入数字"));
  158. } else {
  159. callback();
  160. }
  161. };
  162. let checkOriginOrderNo = (rule, value, callback) => {
  163. const reg = /^[0-9a-zA-Z]+$/;
  164. if (value && !reg.test(value)) {
  165. return callback(new Error("请输入数字和字母"));
  166. } else {
  167. callback();
  168. }
  169. };
  170. return {
  171. action: "",
  172. id: "",
  173. form: {
  174. uid: "",
  175. productTitle: "",
  176. productType: "",
  177. orderType: "",
  178. price: "",
  179. channel: "",
  180. outOrderId: "",
  181. productId: "",
  182. originOrderNo: "",
  183. publicComment: "",
  184. privateComment: "",
  185. orderNo: "",
  186. status: "",
  187. productTypeName: "",
  188. orderTypeName: "",
  189. channelName: ""
  190. },
  191. saveData: {},
  192. rules: {
  193. uid: [{ required: true, message: "请输入用户uid", trigger: "blur" }],
  194. productTitle: [
  195. { required: true, message: "请输入订单名称", trigger: "blur" },
  196. { max: 25, message: "订单名称最多输入25个字", trigger: "blur" }
  197. ],
  198. productType: [
  199. { required: true, message: "请选择订单类型", trigger: "change" }
  200. ],
  201. orderType: [
  202. { required: true, message: "请选择交易类型", trigger: "change" }
  203. ],
  204. price: [{ validator: checkPrice, trigger: "blur" }],
  205. originOrderNo: [{ validator: checkOriginOrderNo, trigger: "blur" }],
  206. productId: [{ validator: checkProductId, trigger: "blur" }],
  207. publicComment: [
  208. { max: 50, message: "外部备注最多输入50个字", trigger: "blur" }
  209. ],
  210. privateComment: [
  211. { required: true, message: "请输入内部备注", trigger: "blur" },
  212. {
  213. max: 10000,
  214. message: "内部备注最多输入10000个字符",
  215. trigger: "blur"
  216. }
  217. ]
  218. },
  219. orderTypes: [],
  220. productTypes: [],
  221. channels: [],
  222. orderState: [],
  223. hasSave: false,
  224. radio: "1",
  225. editorOption: {
  226. modules: {
  227. toolbar: [
  228. ["bold", "italic", "underline", "strike"], // toggled buttons
  229. ["blockquote", "code-block"],
  230. [{ header: 1 }, { header: 2 }], // custom button values
  231. [{ list: "ordered" }, { list: "bullet" }],
  232. [{ script: "sub" }, { script: "super" }], // superscript/subscript
  233. [{ indent: "-1" }, { indent: "+1" }], // outdent/indent
  234. [{ direction: "rtl" }], // text direction
  235. [{ size: ["small", false, "large", "huge"] }], // custom dropdown
  236. [{ header: [1, 2, 3, 4, 5, 6, false] }],
  237. [{ font: [] }],
  238. ["clean"], // remove formatting button
  239. ["link", "image"]
  240. ],
  241. imageResize: {}
  242. }
  243. }
  244. };
  245. },
  246. // computed: {
  247. // radio() {
  248. // if (this.form.orderType === 2 || this.form.orderType === 5 || this.form.orderType === 8) {
  249. // this.radio = "1"
  250. // } else if (this.form.orderType === 9) {
  251. // this.radio = "2"
  252. // } else {
  253. // this.radio = "3"
  254. // }
  255. // }
  256. // },
  257. watch: {
  258. "form.orderType": {
  259. handler() {
  260. if (
  261. this.form.orderType === 2 ||
  262. this.form.orderType === 5 ||
  263. this.form.orderType === 8
  264. ) {
  265. this.radio = "1";
  266. } else if (this.form.orderType === 9) {
  267. this.radio = "2";
  268. } else {
  269. this.radio = "3";
  270. }
  271. }
  272. }
  273. },
  274. mounted() {
  275. if (this.$refs.myQuillEditor) {
  276. this.$refs.myQuillEditor.quill
  277. .getModule("toolbar")
  278. .addHandler("image", this.imgHandler);
  279. }
  280. const type = this.$route.query.type;
  281. if (type === "create") {
  282. this.action = "create";
  283. this.getAllChoice();
  284. } else if (type === "edit") {
  285. this.action = "create";
  286. this.id = this.$route.query.id;
  287. this.hasSave = true;
  288. this.getAllChoice();
  289. this.getOrder();
  290. }
  291. },
  292. methods: {
  293. async getAllChoice() {
  294. let res = await this.$post("/api/admin/order/get_all_choice", {
  295. action: this.action
  296. });
  297. if (res) {
  298. console.log(res);
  299. const allChoice = res.data;
  300. this.orderTypes = allChoice.order_types;
  301. this.productTypes = allChoice.product_types;
  302. this.channels = allChoice.channels;
  303. this.orderState = allChoice.order_state;
  304. }
  305. },
  306. async getOrder() {
  307. let res = await this.$post("/api/admin/order/get", {
  308. order_no: this.id
  309. });
  310. if (res) {
  311. if (res.status === 1 && res.data) {
  312. const data = res.data;
  313. this.form.uid = data.uid || "";
  314. this.form.productTitle = data.product_title || "";
  315. this.form.productType = data.product_type || "";
  316. this.form.orderType = data.order_type || "";
  317. this.form.price = data.price.replace("-", "") || "";
  318. this.form.channel = data.channel || "";
  319. this.form.outOrderId = data.out_order_id || "";
  320. this.form.productId = data.product_id || "";
  321. this.form.originOrderNo = data.origin_order_no || "";
  322. this.form.publicComment = data.public_comment || "";
  323. this.form.privateComment = data.private_comment || "";
  324. this.form.orderNo = data.order_no || "";
  325. this.form.status = data.status || "";
  326. this.form.productTypeName = data.product_type_name || "";
  327. this.form.orderTypeName = data.order_type_name || "";
  328. this.form.channelName = data.channel_name || "";
  329. console.log(this.form);
  330. }
  331. }
  332. },
  333. async saveOrder() {
  334. const data = {
  335. id: this.id,
  336. uid: this.form.uid,
  337. product_title: this.form.productTitle,
  338. product_type: this.form.productType,
  339. order_type: this.form.orderType,
  340. price: this.form.price,
  341. channel: this.form.channel,
  342. out_order_id: this.form.outOrderId,
  343. origin_order_no: this.form.originOrderNo,
  344. public_comment: this.form.publicComment,
  345. private_comment: this.form.privateComment
  346. };
  347. this.saveData = data;
  348. let res = await this.$post("/api/admin/order/create", data);
  349. if (res) {
  350. if (res.status === 1) {
  351. this.id = res.data.id;
  352. this.saveData.id = res.data.id;
  353. this.form.orderNo = res.data.order_no;
  354. this.hasSave = true;
  355. this.$message({
  356. message: "保存成功",
  357. type: "success"
  358. });
  359. } else if (res.status === -2) {
  360. this.$message({
  361. message: `当前订单用户的账户余额不足(可用余额${res.data.can_use}元),操作失败!`,
  362. type: "error"
  363. });
  364. } else if (res.info) {
  365. console.log(res.info);
  366. }
  367. }
  368. },
  369. async confirmOrder() {
  370. const data = {
  371. id: this.id,
  372. uid: this.form.uid,
  373. product_title: this.form.productTitle,
  374. product_type: this.form.productType,
  375. order_type: this.form.orderType,
  376. price: this.form.price,
  377. channel: this.form.channel,
  378. out_order_id: this.form.outOrderId,
  379. origin_order_no: this.form.originOrderNo,
  380. public_comment: this.form.publicComment,
  381. private_comment: this.form.privateComment
  382. };
  383. const confirmData = data;
  384. const saveData = this.saveData;
  385. const isConfirm = true;
  386. for (const key in confirmData) {
  387. if (confirmData[key] !== saveData[key]) {
  388. console.log(confirmData[key], saveData[key]);
  389. this.$message({
  390. message: "与保存订单不一致,请先保存订单!",
  391. type: "warning"
  392. });
  393. return;
  394. }
  395. }
  396. let res = await this.$post("/api/admin/order/confirm_order", data);
  397. if (res) {
  398. if (res.status === 1) {
  399. this.$message({
  400. message: "提交成功",
  401. type: "success"
  402. });
  403. setTimeout(() => {
  404. this.$router.push("/main/artificial_orders");
  405. }, 1000);
  406. } else if (res.info) {
  407. console.log(res.info);
  408. }
  409. }
  410. },
  411. saveSubmit() {
  412. this.$refs["form"].validate(valid => {
  413. if (valid) {
  414. this.saveOrder();
  415. } else {
  416. console.log("error submit!!");
  417. return false;
  418. }
  419. });
  420. },
  421. confirmSubmit() {
  422. this.$refs["form"].validate(valid => {
  423. if (valid) {
  424. this.$confirm(
  425. `确认提价订单后,${this.form.uid}的账户将${this.form.orderTypeName}${this.form.price}元 ,交易方式为${this.form.channelName},请您再次确认操作!`,
  426. "提示",
  427. {
  428. confirmButtonText: "确定",
  429. cancelButtonText: "取消",
  430. type: "warning"
  431. }
  432. )
  433. .then(() => {
  434. this.confirmOrder();
  435. })
  436. .catch(() => {
  437. this.$message({
  438. type: "info",
  439. message: "已取消提交"
  440. });
  441. });
  442. } else {
  443. console.log("error submit!!");
  444. return false;
  445. }
  446. });
  447. },
  448. cancelSubmit() {
  449. this.$router.push("/main/artificial_orders");
  450. },
  451. productTypeChange() {
  452. const productTypeObject = this.productTypes.find(element => {
  453. return element.name === this.form.productTypeName;
  454. });
  455. this.form.productType = productTypeObject.id;
  456. },
  457. orderTypeChange() {
  458. const orderTypeObject = this.orderTypes.find(element => {
  459. return element.name === this.form.orderTypeName;
  460. });
  461. this.form.orderType = orderTypeObject.id;
  462. },
  463. channelChange() {
  464. const channelObject = this.channels.find(element => {
  465. return element.name === this.form.channelName;
  466. });
  467. this.form.channel = channelObject.id;
  468. },
  469. imgHandler(state) {
  470. if (state) {
  471. //触发input的单击 ,fileBtn换成自己的
  472. this.$refs.fileBtn.click();
  473. }
  474. },
  475. handleChange(e) {
  476. const files = e.target.files;
  477. if (!files) {
  478. return;
  479. }
  480. const file = files[0];
  481. // if (file.size / 1024 > 500) {
  482. // this.$message.error("图片大小不得超过500k,请重新选择");
  483. // return false;
  484. // }
  485. console.log(file);
  486. const formData = new FormData();
  487. formData.append("file", file);
  488. formData.append("original_filename", file.name);
  489. console.log(formData);
  490. this.$axios
  491. .$post("/upload_image", formData, {
  492. headers: { "Content-Type": "multipart/form-data" }
  493. })
  494. .then(res => {
  495. console.log(res);
  496. const index = this.myQuillEditor.selection.savedRange.index;
  497. this.myQuillEditor.insertEmbed(index, "image", res.filename);
  498. // this.$emit(
  499. // "change",
  500. // this.content + `<img src="${res.filename}" alt="${file.name}"/>`
  501. // );
  502. });
  503. }
  504. }
  505. };
  506. </script>
  507. <style lang="scss" scoped>
  508. .box-card {
  509. margin-bottom: 10px;
  510. width: 100%;
  511. }
  512. .header {
  513. font-size: 24px;
  514. color: #222222;
  515. font-weight: 600;
  516. }
  517. .clearfix:before,
  518. .clearfix:after {
  519. display: table;
  520. content: "";
  521. }
  522. .clearfix:after {
  523. clear: both;
  524. }
  525. .order-number {
  526. display: flex;
  527. align-items: center;
  528. }
  529. .order-number span:first-child {
  530. flex: 1;
  531. font-size: 14px;
  532. color: #999999;
  533. }
  534. .order-number span:nth-child(2) {
  535. font-size: 14px;
  536. color: #999999;
  537. }
  538. .order-status {
  539. display: block;
  540. margin-left: 7px;
  541. padding: 0 2px;
  542. height: 22px;
  543. line-height: 22px;
  544. border: 1px solid #3c95ff;
  545. font-size: 12px;
  546. color: #308eff;
  547. }
  548. .el-select {
  549. width: 100%;
  550. }
  551. .editer {
  552. width: 100%;
  553. height: 600px;
  554. padding: 0 0 50px;
  555. }
  556. .save-btn {
  557. width: 100px;
  558. height: 40px;
  559. }
  560. .cancel-btn {
  561. margin-left: 10px;
  562. width: 100px;
  563. height: 40px;
  564. }
  565. .comfirm-btn {
  566. width: 210px;
  567. height: 40px;
  568. }
  569. </style>