online-exam-form.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. <template>
  2. <el-form
  3. v-loading="loading"
  4. ref="ruleForm"
  5. :model="ruleForm"
  6. status-icon
  7. :rules="rulesThis"
  8. :label-width="labelWidth || '100px'"
  9. class="demo-ruleForm"
  10. :size="size || 'medium'"
  11. >
  12. <el-row>
  13. <el-col :span="24" style="padding: 0 0 20px 0">
  14. <el-row>
  15. <el-col :span="20">
  16. <el-alert
  17. title="特别关注:手动到对接平台修改商品信息,会被本系统强制覆盖,请谨慎操作!"
  18. type="error"
  19. show-icon
  20. description=""
  21. :size="'mini'"
  22. :closable="false"
  23. >
  24. </el-alert
  25. ></el-col>
  26. <el-col :span="4">
  27. <el-button
  28. v-if="!isDetail"
  29. :size="'mini'"
  30. type="primary"
  31. class="fr"
  32. @click="submitForm()"
  33. >保 存
  34. </el-button>
  35. </el-col>
  36. </el-row>
  37. </el-col>
  38. <el-col :span="6"
  39. ><el-form-item label="审核状态" prop="exam_status">
  40. <el-radio-group
  41. v-model="ruleForm.exam_status"
  42. placeholder="请选择审核状态"
  43. style="width: 100%"
  44. :size="size || 'medium'"
  45. @change="exam_statusChange"
  46. >
  47. <el-radio
  48. v-for="item in exam_statusList"
  49. :key="item.value"
  50. :label="item.value"
  51. >{{ item.label }}</el-radio
  52. >
  53. </el-radio-group>
  54. </el-form-item>
  55. </el-col>
  56. <el-col :span="18" v-if="String(ruleForm.exam_status) === '1'">
  57. <el-row>
  58. <el-col :span="24">
  59. <el-form-item label="有赞公用分类" prop="yz_cat_id" label-width="120px">
  60. <good-class-youzan
  61. :value="ruleForm.yz_cat_id"
  62. :placeholder="'请选择分类'"
  63. @handleChange="handleChange"
  64. />
  65. </el-form-item>
  66. </el-col>
  67. </el-row>
  68. </el-col>
  69. <el-col
  70. :span="24"
  71. v-show="String(ruleForm.exam_status) === '1'"
  72. style="padding: 0 0 10px 0"
  73. >
  74. <el-row>
  75. <el-col :span="6">
  76. <el-form-item label="商品类型" prop="item_type">
  77. <el-select
  78. v-model="ruleForm.item_type"
  79. placeholder="请选择商品类型"
  80. style="width: 100%"
  81. >
  82. <el-option
  83. v-for="item in item_type_options"
  84. :key="item.label + item.value"
  85. :label="item.label"
  86. :value="item.value"
  87. :disabled="String(item.status) === '0'"
  88. >
  89. </el-option>
  90. </el-select>
  91. </el-form-item>
  92. </el-col>
  93. <el-col :span="10">
  94. <el-form-item label="开始出售时间" prop="time" label-width="120px">
  95. <ul class="item_auto_listing_time clearfix">
  96. <li class="fl" style="width: 100px">
  97. <el-radio
  98. v-model="ruleForm.item_auto_listing_time"
  99. label="0"
  100. @change="item_auto_change"
  101. >立即出售</el-radio
  102. >
  103. </li>
  104. <li class="fl">
  105. <el-date-picker
  106. v-model="ruleForm.auto_listing_time"
  107. type="datetime"
  108. style="width: 100%"
  109. value-format="yyyy-MM-dd HH:mm:ss"
  110. placeholder="选择开始出售时间"
  111. default-time="12:00:00"
  112. @change="time_change"
  113. :picker-options="pickerOptions"
  114. >
  115. </el-date-picker>
  116. </li>
  117. </ul>
  118. </el-form-item>
  119. </el-col>
  120. <el-col :span="8">
  121. <el-form-item label="划线价" prop="origin">
  122. <digital-input
  123. :values="ruleForm.origin"
  124. :placeholder="'起订量'"
  125. :min="0"
  126. :max="100000000000"
  127. :position="'right'"
  128. :precision="2"
  129. :controls="false"
  130. :append="''"
  131. :newTime="''"
  132. :size="''"
  133. :disabled="false"
  134. @reschange="num_change($event, 'origin', -1)"
  135. />
  136. </el-form-item>
  137. </el-col>
  138. </el-row>
  139. </el-col>
  140. <el-col :span="24">
  141. <el-form-item label-width="140px" prop="distribution" label="支持的配送方式">
  142. <el-checkbox-group v-model="ruleForm.distribution" @change="handleChange">
  143. <el-checkbox label="1" key="1">快递发货</el-checkbox>
  144. <el-checkbox label="2" key="2" >同城配送</el-checkbox>
  145. <el-checkbox label="3" key="3">到店自提</el-checkbox>
  146. </el-checkbox-group>
  147. </el-form-item>
  148. </el-col>
  149. <el-col
  150. :span="24"
  151. v-show="String(ruleForm.exam_status) === '1'"
  152. style="padding: 0 0 10px 0"
  153. >
  154. <!-- @current-change="handleCurrentChange" -->
  155. <el-table
  156. :data="nakelist"
  157. :size="'mini'"
  158. border
  159. stripe
  160. highlight-current-row
  161. ref="singleTable"
  162. >
  163. <el-table-column label="系统阶梯" width="80px">
  164. <template slot-scope="scope">
  165. <i
  166. v-if="currentRow && String(currentRow.id) === String(scope.row.id)"
  167. class="el-icon-check"
  168. style="color: #1890ff; font-size: 16px; font-weight: bolder"
  169. /> </template
  170. ></el-table-column>
  171. <el-table-column prop="min_num" label="采购起订量" />
  172. <el-table-column label="销售">
  173. <el-table-column prop="start_sale_num" label="起订量">
  174. <template slot-scope="scope">
  175. <span>
  176. {{ scope.row.start_sale_num }}
  177. </span>
  178. </template>
  179. </el-table-column>
  180. <el-table-column prop="sale_good_price" label="系统售价" />
  181. <el-table-column prop="sale_cost_fee" label="系统工艺费" />
  182. <el-table-column prop="final_price" label="最终售价">
  183. <template slot-scope="scope">
  184. <digital-input
  185. v-show="scope.row.edit"
  186. :values="scope.row.final_price"
  187. :placeholder="'最终售价'"
  188. :min="scope.row.sale_good_price"
  189. :max="9999999"
  190. :position="'right'"
  191. :precision="2"
  192. :controls="false"
  193. :append="''"
  194. :newTime="scope.row.newTime"
  195. :size="'mini'"
  196. :disabled="false"
  197. @reschange="num_change($event, 'final_price', scope.$index)"
  198. />
  199. <span v-show="!scope.row.edit">
  200. {{ scope.row.final_price }}
  201. </span>
  202. </template>
  203. </el-table-column>
  204. </el-table-column>
  205. </el-table>
  206. </el-col>
  207. <el-col :span="18" v-show="ruleForm.exam_status + '' !== '1'">
  208. <el-form-item label="审核备注" prop="reject_reason">
  209. <el-input
  210. type="textarea"
  211. placeholder="审核备注"
  212. v-model="ruleForm.reject_reason"
  213. :disabled="disabled"
  214. maxlength="250"
  215. show-word-limit
  216. :autosize="{ minRows: 3, maxRows: 3 }"
  217. />
  218. </el-form-item>
  219. </el-col>
  220. </el-row>
  221. </el-form>
  222. </template>
  223. <script>
  224. import asyncRequest from "@/apis/service/youzan/othgoodsOnline";
  225. import { item_type_options } from "../columns";
  226. export default {
  227. name: "exam-form",
  228. props: ["size", "statusList", "disabled", "isMust", "labelWidth", "time", "sitem"],
  229. /**
  230. * 属性集合
  231. * @param {String} size : 组件大小 非必填
  232. * @param {Array} statusList : 驳回至备选项 必填
  233. * @param {Boolean} disabled : 是否禁用 必填
  234. * @param {Boolean} isMust : 是否需要展示驳回节点 必填
  235. */
  236. /**
  237. * 事件集合
  238. * @searchChange : 选中值变化调用 抛出选中数据
  239. */
  240. data() {
  241. const validatetime = (rule, value, callback) => {
  242. const { item_auto_listing_time, auto_listing_time } = this.ruleForm;
  243. const type = item_auto_listing_time ?? "";
  244. const time = auto_listing_time ?? "";
  245. // console.log(item_auto_listing_time, auto_listing_time);
  246. if (type === "" && time === "") {
  247. callback(new Error("请选择开始出售时间!"));
  248. } else {
  249. callback();
  250. }
  251. };
  252. const validate_num_0 = (rule, value, callback) => {
  253. const val = value ?? "";
  254. const { required } = rule;
  255. if (required && val === "") {
  256. callback(new Error("不能为空!"));
  257. } else if (
  258. required &&
  259. (val === "0" ||
  260. val === "0." ||
  261. val === "0.0" ||
  262. val === "0.00" ||
  263. val === "0.000")
  264. ) {
  265. callback(new Error("不能为零!"));
  266. } else {
  267. callback();
  268. }
  269. };
  270. return {
  271. platform_id: "",
  272. spuCode: "",
  273. loading: true,
  274. currentRow: null,
  275. nakelist: [],
  276. tags_options: [],
  277. item_type_options,
  278. exam_statusList: [
  279. {
  280. value: "1",
  281. label: "通过",
  282. },
  283. {
  284. value: "2",
  285. label: "驳回",
  286. },
  287. ],
  288. is_support_barter_list: [
  289. {
  290. value: "1",
  291. label: "支持",
  292. },
  293. {
  294. value: "0",
  295. label: "不支持",
  296. },
  297. ],
  298. showModelThis: this.showModel,
  299. pickerOptions: {
  300. disabledDate: (time) => {
  301. return time.getTime() < new Date().valueOf() - 1000 * 60 * 60 * 24;
  302. },
  303. },
  304. ruleForm: {
  305. exam_status: "1", // 通过or驳回
  306. yz_cat_id: [],
  307. rebut: "", //驳回至
  308. reject_reason: "",
  309. tags: [],
  310. item_type: "0",
  311. item_auto_listing_time: "0",
  312. auto_listing_time: "",
  313. origin: "0",
  314. time: "0",
  315. distribution: ['1']
  316. },
  317. rulesThis: this.rules,
  318. rules: {
  319. exam_status: [
  320. {
  321. required: true,
  322. message: "请选择审核状态",
  323. trigger: "change",
  324. },
  325. ],
  326. is_support_barter: [
  327. {
  328. required: false,
  329. message: "请选择是否可退",
  330. trigger: "change",
  331. },
  332. ],
  333. tags: [
  334. {
  335. required: false,
  336. type: "array",
  337. trigger: "change",
  338. },
  339. ],
  340. yz_cat_id: [
  341. {
  342. required: true,
  343. type: "array",
  344. message: "请选择有赞公用分类",
  345. trigger: "change",
  346. },
  347. ],
  348. reject_reason: [
  349. { required: true, message: "请输入审核备注", trigger: "blur" },
  350. {
  351. min: 1,
  352. max: 250,
  353. message: "长度在 1 到 250 个字符",
  354. trigger: "blur",
  355. },
  356. ],
  357. origin: [
  358. {
  359. required: true,
  360. validator: validate_num_0,
  361. trigger: "blur",
  362. },
  363. ],
  364. distribution:[
  365. {
  366. type:'array',
  367. required: true,
  368. trigger:'change',
  369. message:'请选择支持的配送方式'
  370. }
  371. ],
  372. time: [
  373. {
  374. required: true,
  375. validator: validatetime,
  376. trigger: "change,blur",
  377. },
  378. ],
  379. item_type: [
  380. {
  381. required: true,
  382. message: "请选择商品类型",
  383. trigger: "change",
  384. },
  385. ],
  386. },
  387. };
  388. },
  389. watch: {
  390. isDetail: function (val, old) {
  391. if (this.isDetail !== val) {
  392. this.options = [];
  393. this.selectLoading = false;
  394. }
  395. },
  396. newTime: function (val) {
  397. if (val) {
  398. this.initForm();
  399. }
  400. },
  401. },
  402. mounted() {
  403. this.initForm();
  404. },
  405. methods: {
  406. handleChange(values){
  407. console.log(values)
  408. },
  409. async initForm() {
  410. // this.loading = true;
  411. this.rulesThis = this.rules;
  412. await this.resetForm();
  413. this.exam_statusChange();
  414. await this.get_tags();
  415. const { nakelist, spuCode, platform_id } = this.sitem;
  416. this.spuCode = spuCode;
  417. this.platform_id = platform_id;
  418. console.log(this.sitem);
  419. this.nakelist = JSON.parse(JSON.stringify(nakelist));
  420. this.nakelist.forEach(async (si, sii) => {
  421. si.start_sale_num = si.min_num;
  422. let { isok, price, sale_cost_fee } = await this.get_new(sii);
  423. if (isok === 0) {
  424. this.nakelist[sii].sale_good_price = price;
  425. this.nakelist[sii].sale_cost_fee = sale_cost_fee;
  426. this.nakelist[sii].newTime = new Date().valueOf() + "";
  427. } else if (isok >= 100 && isok <= 104) {
  428. await this.logout();
  429. } else {
  430. this.nakelist[sii].sale_good_price = price;
  431. this.nakelist[sii].sale_cost_fee = sale_cost_fee;
  432. this.nakelist[sii].newTime = new Date().valueOf() + "";
  433. }
  434. this.$set(this.nakelist, sii, this.nakelist[sii]);
  435. });
  436. // this.setCurrent(this.nakelist[0]);
  437. let index = this.nakelist.findIndex((e) => e.min_num + "" === "1");
  438. if (index !== -1) {
  439. this.handleCurrentChange(this.nakelist[index]);
  440. }
  441. this.loading = false;
  442. },
  443. item_auto_change() {
  444. const { item_auto_listing_time } = this.ruleForm;
  445. if (String(item_auto_listing_time) === "0") {
  446. }
  447. this.ruleForm.auto_listing_time =
  448. String(item_auto_listing_time) === "0" ? "" : this.ruleForm.auto_listing_time;
  449. this.ruleForm.time =
  450. this.ruleForm.item_auto_listing_time || this.ruleForm.auto_listing_time;
  451. this.$refs.ruleForm.validateField("time");
  452. },
  453. time_change() {
  454. const { auto_listing_time } = this.ruleForm;
  455. this.ruleForm.item_auto_listing_time = String(auto_listing_time) === "" ? "0" : "";
  456. this.ruleForm.time =
  457. this.ruleForm.item_auto_listing_time || this.ruleForm.auto_listing_time;
  458. this.$refs.ruleForm.validateField("time");
  459. },
  460. async get_tags() {
  461. const { code, data, message } = await asyncRequest.tag_list({});
  462. if (code === 0) {
  463. this.tags_options = data;
  464. } else if (code >= 100 && code <= 104) {
  465. this.tags_options = [];
  466. await this.logout();
  467. } else {
  468. this.tags_options = [];
  469. this.$message.warning(message);
  470. }
  471. },
  472. exam_statusChange() {
  473. const { exam_status } = this.ruleForm;
  474. const isok = String(exam_status) === "1";
  475. // this.rulesThis.is_support_barter[0].required = isok;
  476. this.rulesThis.yz_cat_id[0].required = isok;
  477. this.rulesThis.item_type[0].required = isok;
  478. this.rulesThis.time[0].required = isok;
  479. this.rulesThis.origin[0].required = isok;
  480. this.rulesThis.reject_reason[0].required = !isok;
  481. },
  482. num_change(e, key, index) {
  483. if (index === -1) {
  484. // console.log(key, e);
  485. this.ruleForm[key] = e;
  486. this.$refs.ruleForm.validateField(key);
  487. } else {
  488. this.nakelist[index][key] = e;
  489. this.nakelist[index].newTime = new Date().valueOf() + "";
  490. // this.$set(this.nakelist, index, this.nakelist[index]);
  491. }
  492. },
  493. handleChange(e) {
  494. this.ruleForm.yz_cat_id = e;
  495. this.$refs.ruleForm.validateField("yz_cat_id");
  496. },
  497. // setCurrent(row) {
  498. // this.$refs.singleTable.setCurrentRow(row);
  499. // },
  500. async get_new(index) {
  501. console.log(index);
  502. const { min_num } = this.nakelist[index];
  503. const { code, data, message } = await asyncRequest.goodupprice({
  504. min_num: min_num,
  505. platform_id: this.platform_id,
  506. spuCode: this.spuCode,
  507. });
  508. const resModel = {
  509. isok: code,
  510. price: code === 0 ? data.sale_price : "0",
  511. sale_cost_fee: code === 0 ? data.new_cost_fee : "0",
  512. message: message,
  513. };
  514. return resModel;
  515. },
  516. handleCurrentChange(val) {
  517. this.currentRow = val;
  518. const { id } = val;
  519. this.nakelist.forEach((si, sii) => {
  520. this.nakelist[sii].edit = false;
  521. if (id && id === si.id) {
  522. this.nakelist[sii].edit = true;
  523. }
  524. this.$set(this.nakelist, sii, this.nakelist[sii]);
  525. });
  526. },
  527. async resetForm() {
  528. // 重置
  529. await this.$nextTick(() => {
  530. if (this.$refs.ruleForm) {
  531. this.$refs.ruleForm.resetFields();
  532. this.$refs.ruleForm.clearValidate();
  533. this.ruleForm = {
  534. exam_status: "1", // 通过or驳回
  535. yz_cat_id: [],
  536. is_support_barter: "1",
  537. reject_reason: "",
  538. tags: [],
  539. item_type: "0",
  540. item_auto_listing_time: "0",
  541. auto_listing_time: "",
  542. origin: "0",
  543. time: "0",
  544. distribution : ['1']
  545. };
  546. }
  547. });
  548. },
  549. async submitForm() {
  550. await this.$refs.ruleForm.validate(async (valid) => {
  551. if (valid) {
  552. if (this.loading) return;
  553. await this.$confirm(`确定要提交?`, {
  554. confirmButtonText: "确定",
  555. cancelButtonText: "取消",
  556. type: "warning",
  557. })
  558. .then(async () => {
  559. this.loading = true;
  560. let model = JSON.parse(JSON.stringify(this.ruleForm));
  561. const {
  562. yz_cat_id,
  563. item_auto_listing_time,
  564. auto_listing_time,
  565. origin,
  566. } = this.ruleForm;
  567. // console.log(yz_cat_id);
  568. model.platform_youzan_id = this.sitem.platform_youzan_id;
  569. model.yz_cat_id = "";
  570. model.good_ladder_id = "";
  571. model.final_price = "";
  572. model.start_sale_num = "";
  573. const { exam_status } = this.ruleForm;
  574. const isok = String(exam_status) === "1";
  575. if (isok) {
  576. const { id } = this.currentRow;
  577. if (!id) {
  578. this.$message.warning("请选择一个系统阶梯!");
  579. this.loading = false;
  580. return;
  581. }
  582. let is_ok = true;
  583. this.nakelist.forEach((e) => {
  584. if (e.sale_good_price + "" === "0" && e.sale_cost_fee + "" === "0") {
  585. is_ok = false;
  586. }
  587. });
  588. if (!is_ok) {
  589. this.$message.warning("暂无系统售价,请设置毛利率!");
  590. this.loading = false;
  591. return;
  592. }
  593. let index = this.nakelist.findIndex((si) => si.id === id);
  594. const {
  595. min_num,
  596. start_sale_num,
  597. sale_good_price,
  598. sale_cost_fee,
  599. final_price,
  600. } = this.nakelist[index];
  601. if (parseInt(start_sale_num) < parseInt(min_num)) {
  602. this.$message.warning("销售起订量不小于采购起订量!");
  603. this.loading = false;
  604. return;
  605. }
  606. if (!final_price) {
  607. this.$message.warning("最终售价不能为空!");
  608. this.loading = false;
  609. return;
  610. }
  611. if (sale_good_price * 100 > final_price * 100) {
  612. this.$message.warning("最终价格不小于系统售价");
  613. this.loading = false;
  614. return;
  615. }
  616. let am = 0;
  617. const m = auto_listing_time ?? "",
  618. nm = new Date().valueOf(),
  619. fp = final_price * 100,
  620. op = origin * 100;
  621. if (m !== "0") {
  622. am = new Date(auto_listing_time).valueOf();
  623. }
  624. if (am !== 0 && nm >= am) {
  625. this.$message.warning("开始出售时间不能小于当前时间!");
  626. this.loading = false;
  627. return;
  628. }
  629. if (op < fp) {
  630. this.$message.warning("划线价不能小于最终售价!");
  631. this.loading = false;
  632. return;
  633. }
  634. model.platform_youzan_id = this.sitem.platform_youzan_id;
  635. model.yz_cat_id = yz_cat_id[yz_cat_id.length - 1];
  636. model.good_ladder_id = id;
  637. model.final_price = final_price;
  638. model.start_sale_num = start_sale_num;
  639. model.auto_listing_time =
  640. model.time !== "0" ? new Date(model.time).valueOf() : "0";
  641. delete model["time"];
  642. delete model["item_auto_listing_time"];
  643. }
  644. const { code, message } = await asyncRequest.goodupexam(model);
  645. if (code === 0) {
  646. this.$notify.success({
  647. title: "提交成功!",
  648. message: "",
  649. });
  650. this.$emit("searchChange");
  651. } else if (code >= 100 && code <= 104) {
  652. await this.logout();
  653. } else {
  654. this.$message.warning(message);
  655. }
  656. })
  657. .catch(() => {
  658. console.log("取消");
  659. });
  660. } else {
  661. console.log("error submit!!");
  662. return false;
  663. }
  664. });
  665. },
  666. async setstatus(model) {},
  667. },
  668. };
  669. </script>
  670. <style>
  671. .item_auto_listing_time .fl:last-child {
  672. width: calc(100% - 115px);
  673. }
  674. </style>