dislogSet.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. <template>
  2. <div>
  3. <BaseDialog
  4. width="1800px"
  5. :isShow.sync="isShow"
  6. :title="title"
  7. @close="close"
  8. @submit="submitForm"
  9. >
  10. <div class="bop-tip">
  11. <div><i class="el-icon-warning-outline"></i>说明</div>
  12. <div>
  13. 如果提成方式是按阶梯价计算,则需设置阶梯价格区间(最高价无穷大,则填写
  14. “ * ” )。如果无需按阶梯价计算提成,留空即可。
  15. </div>
  16. </div>
  17. <el-form
  18. inline
  19. hide-required-asterisk
  20. :model="form"
  21. :rules="rules"
  22. ref="form"
  23. >
  24. <div>
  25. <el-form-item prop="tpName" label="模板名称:" label-width="100px">
  26. <el-input
  27. placeholder="请输入模板名称"
  28. v-model="form.tpName"
  29. ></el-input>
  30. </el-form-item>
  31. <el-form-item prop="tenantId" label="">
  32. <el-select
  33. filterable
  34. v-model="form.tenantId"
  35. placeholder="请选择关联机构"
  36. >
  37. <el-option
  38. v-for="item in tenantList"
  39. :key="item.tenantId"
  40. :label="item.tenantName"
  41. :value="item.tenantId"
  42. ></el-option>
  43. </el-select>
  44. </el-form-item>
  45. <el-form-item label="">
  46. <el-checkbox
  47. :true-label="1"
  48. :false-label="0"
  49. v-model="form.defaultStatus"
  50. >默认</el-checkbox
  51. >
  52. </el-form-item>
  53. </div>
  54. <div v-for="(item, index) in form.itemList" :key="index">
  55. <el-form-item
  56. :prop="'itemList.' + index + '.itemName'"
  57. :label="index == 0 ? '成本设置:' : ' '"
  58. :rules="rules['itemName']"
  59. label-width="100px"
  60. >
  61. <el-input
  62. placeholder="请输入成本项名称"
  63. v-model="item.itemName"
  64. ></el-input>
  65. </el-form-item>
  66. <el-form-item
  67. label=""
  68. :prop="'itemList.' + index + '.itemCategory'"
  69. :rules="rules['itemCategory']"
  70. >
  71. <el-select v-model="item.itemCategory" placeholder="请选择成本类型">
  72. <el-option label="分成成本" :value="1"></el-option>
  73. <el-option label="其他成本" :value="2"></el-option>
  74. </el-select>
  75. </el-form-item>
  76. <el-form-item
  77. label=""
  78. :prop="'itemList.' + index + '.educationTypeId'"
  79. :rules="rules['educationTypeId']"
  80. >
  81. <el-select
  82. @change="changeEdu(item)"
  83. v-model="item.educationTypeId"
  84. placeholder="请选择教育类型"
  85. >
  86. <el-option
  87. v-for="item in eduList"
  88. :key="item.id"
  89. :label="
  90. item.schemeName +
  91. (item.schemeName ? '-' : '') +
  92. item.educationName
  93. "
  94. :value="item.id"
  95. >
  96. </el-option>
  97. </el-select>
  98. </el-form-item>
  99. <el-form-item
  100. v-if="item.educationTypeId != -1"
  101. label=""
  102. :prop="'itemList.' + index + '.businessId'"
  103. :rules="rules['businessId']"
  104. >
  105. <el-select
  106. filterable
  107. v-model="item.businessId"
  108. placeholder="请选择业务层次"
  109. >
  110. <el-option
  111. v-for="level in backbusinessList(item.educationTypeId)"
  112. :key="level.businessId"
  113. :label="level.aliasName"
  114. :value="level.businessId"
  115. @click.native="changeBus(item, level.projectId)"
  116. >
  117. </el-option>
  118. </el-select>
  119. </el-form-item>
  120. <el-form-item
  121. label=""
  122. :prop="'itemList.' + index + '.itemType'"
  123. :rules="rules['itemType']"
  124. >
  125. <el-select v-model="item.itemType" placeholder="请选择成本类型">
  126. <el-option label="百分比成本" :value="1"></el-option>
  127. <el-option label="固定成本" :value="2"></el-option>
  128. </el-select>
  129. </el-form-item>
  130. <el-form-item
  131. label=""
  132. :prop="'itemList.' + index + '.minValue'"
  133. :rules="rules['minValue']"
  134. class="range"
  135. >
  136. <el-col :span="11">
  137. <el-input
  138. v-int
  139. placeholder="最低价"
  140. v-model.number="item.minValue"
  141. ></el-input>
  142. </el-col>
  143. <el-col class="line" :span="2" style="magrin: 10px">-</el-col>
  144. <el-col :span="11">
  145. <el-input
  146. v-int
  147. placeholder="最高价"
  148. @change="changeMaxValue('itemList.' + index + '.minValue')"
  149. v-model.number="item.maxValue"
  150. ></el-input>
  151. </el-col>
  152. </el-form-item>
  153. <el-form-item
  154. v-if="item.itemType"
  155. class="ddd"
  156. label-width="0"
  157. :prop="'itemList.' + index + '.typeValue'"
  158. label=" "
  159. :rules="rules['typeValue']"
  160. >
  161. <el-input
  162. v-if="item.itemType == 1"
  163. placeholder="输入百分比"
  164. v-model="item.typeValue"
  165. key="2"
  166. v-int="{ max: 100 }"
  167. >
  168. <template slot="append"> % </template>
  169. </el-input>
  170. <el-input
  171. key="1"
  172. v-else
  173. placeholder="固定金额"
  174. v-model="item.typeValue"
  175. v-int
  176. >
  177. <template slot="append"> 元 </template>
  178. </el-input>
  179. </el-form-item>
  180. <el-form-item label="" v-if="item.itemCategory == 1">
  181. <el-checkbox
  182. :true-label="1"
  183. :false-label="0"
  184. v-model="item.dockStatus"
  185. >成本扣除</el-checkbox
  186. >
  187. </el-form-item>
  188. <template v-if="item.dockStatus == 1">
  189. <el-form-item
  190. label=""
  191. :prop="'itemList.' + index + '.dockType'"
  192. :rules="rules['dockType']"
  193. >
  194. <el-select v-model="item.dockType" placeholder="请选择扣除类型">
  195. <el-option label="百分比扣除" :value="1"></el-option>
  196. <el-option label="固定扣除" :value="2"></el-option>
  197. </el-select>
  198. </el-form-item>
  199. <el-form-item
  200. v-if="item.dockType"
  201. class="ddd"
  202. label-width="0"
  203. :prop="'itemList.' + index + '.dockValue'"
  204. label=" "
  205. :rules="rules['dockValue']"
  206. >
  207. <el-input
  208. v-if="item.dockType == 1"
  209. placeholder="输入百分比"
  210. v-model="item.dockValue"
  211. key="2"
  212. v-int="{ max: 100 }"
  213. >
  214. <template slot="append"> % </template>
  215. </el-input>
  216. <el-input
  217. key="1"
  218. v-else
  219. placeholder="固定金额"
  220. v-model="item.dockValue"
  221. v-int
  222. >
  223. <template slot="append"> 元 </template>
  224. </el-input>
  225. </el-form-item>
  226. </template>
  227. <el-form-item label-width="0" label=" ">
  228. <div class="btns">
  229. <i @click="add(index, item)" class="el-icon-connection"></i>
  230. <i @click="add(index)" class="el-icon-circle-plus-outline"></i>
  231. <i
  232. v-if="index != 0"
  233. @click="del(index)"
  234. class="el-icon-remove-outline"
  235. ></i>
  236. </div>
  237. </el-form-item>
  238. </div>
  239. </el-form>
  240. </BaseDialog>
  241. </div>
  242. </template>
  243. <script>
  244. import { eduList, addCost, costDetail, editCost } from "@/api/financed/index";
  245. export default {
  246. name: "DislogSet",
  247. props: {
  248. dialogVisible: {
  249. type: Boolean,
  250. default: false,
  251. },
  252. // 0 新增 1修改 2复制 3订单成本设置 4批量设置
  253. type: {
  254. type: [String, Number],
  255. default: 0,
  256. },
  257. tpId: {
  258. type: [String, Number],
  259. default: "",
  260. },
  261. },
  262. data() {
  263. var checkMinValue = (rule, value, callback) => {
  264. const list = this.itemList[rule.field.split(".")[1]];
  265. const { maxValue, businessId } = list;
  266. if (maxValue || value || value === 0) {
  267. if (!value && value !== 0) {
  268. callback(new Error("请输入最低价"));
  269. } else if (!maxValue) {
  270. callback(new Error("请输入最高价"));
  271. } else if (maxValue <= value) {
  272. callback(new Error("最低价不能小于最高价"));
  273. }
  274. }
  275. if (businessId) {
  276. const levelList = this.itemList.filter(
  277. (e) => e.businessId == list.businessId
  278. );
  279. if (levelList.length > 1) {
  280. const text = this.isHaveIntersect(levelList);
  281. text && callback(new Error(text));
  282. }
  283. }
  284. callback();
  285. };
  286. var checkEduId = (rule, value, callback) => {
  287. const len = this.itemList.length;
  288. if (len > 1) {
  289. const len1 = this.itemList.filter(
  290. (e) => e.educationTypeId == -1
  291. ).length;
  292. if (len1 > 0 && len1 != len) {
  293. callback(new Error("需统一不限!"));
  294. }
  295. }
  296. callback();
  297. };
  298. var checkBusId = (rule, value, callback) => {
  299. const { educationTypeId } = this.itemList[rule.field.split(".")[1]];
  300. if (this.itemList.length > 1) {
  301. const flag = this.itemList.some(
  302. (e) => e.educationTypeId == educationTypeId && e.businessId == -1
  303. );
  304. if (flag) {
  305. const flag1 = this.itemList.some(
  306. (e) => e.educationTypeId == educationTypeId && e.businessId != -1
  307. );
  308. flag1 && callback(new Error("需统一不限!"));
  309. }
  310. }
  311. callback();
  312. };
  313. return {
  314. form: {},
  315. rules: {
  316. tpName: [
  317. { required: true, message: "请输入模板名称", trigger: "blur" },
  318. ],
  319. tenantId: [
  320. { required: true, message: "请选择关联机构", trigger: "change" },
  321. ],
  322. itemName: [
  323. { required: true, message: "请输入成本项名称", trigger: "blur" },
  324. ],
  325. businessId: [
  326. { required: true, message: "请选择业务层次", trigger: "blur" },
  327. { validator: checkBusId, trigger: "change" },
  328. ],
  329. educationTypeId: [
  330. { required: true, message: "请选择教育类型", trigger: "change" },
  331. { validator: checkEduId, trigger: "change" },
  332. ],
  333. itemCategory: [
  334. { required: true, message: "请选择业务类型", trigger: "change" },
  335. ],
  336. itemType: [
  337. { required: true, message: "请选择成本类型", trigger: "change" },
  338. ],
  339. typeValue: [
  340. { required: true, message: "请输入成本值", trigger: "blur" },
  341. ],
  342. dockType: [
  343. { required: true, message: "请选择扣除类型", trigger: "change" },
  344. ],
  345. dockValue: [
  346. { required: true, message: "请输入扣除值", trigger: "blur" },
  347. ],
  348. minValue: [{ validator: checkMinValue, trigger: "blur" }],
  349. },
  350. tenantList: [],
  351. eduList: [],
  352. };
  353. },
  354. methods: {
  355. init() {
  356. this.resetForm();
  357. if (this.type === 3) {
  358. this.getOrderCostDetail();
  359. } else if (this.type === 4) {
  360. } else {
  361. this.tpId && this.getCostDetail();
  362. }
  363. this.getTenantList();
  364. this.getEduList();
  365. },
  366. getOrderCostDetail() {
  367. this.$api.systemtopordercost(this.tpId).then((res) => {
  368. Object.keys(this.form).map((key) => {
  369. this.form[key] = res.data[key];
  370. });
  371. this.form.itemList.forEach((ele) => {
  372. if (ele.maxValue == -1) {
  373. ele.maxValue = "*";
  374. }
  375. });
  376. });
  377. },
  378. getCostDetail() {
  379. costDetail(this.tpId).then((res) => {
  380. if (this.type == 2) delete this.form["tpId"];
  381. Object.keys(this.form).map((key) => {
  382. this.form[key] = res.data[key];
  383. });
  384. this.form.itemList.forEach((ele) => {
  385. if (ele.maxValue == -1) {
  386. ele.maxValue = "*";
  387. }
  388. });
  389. });
  390. },
  391. getEduList() {
  392. if (this.eduList.length) return;
  393. eduList({}).then((res) => {
  394. this.eduList = [
  395. { schemeName: "", educationName: "不限", id: -1 },
  396. ...res.rows,
  397. ];
  398. });
  399. },
  400. backbusinessList(eduId) {
  401. if (!eduId || !this.eduList.length) return [];
  402. let data = this.eduList.find((e) => e.id == eduId);
  403. return data.businessList
  404. ? [
  405. { aliasName: "不限", businessId: -1, projectId: -1 },
  406. ...data.businessList,
  407. ]
  408. : [];
  409. },
  410. getTenantList() {
  411. if (this.tenantList.length) return;
  412. this.$api.systemtenantlist().then((res) => {
  413. this.tenantList = res.rows;
  414. });
  415. },
  416. changeEdu(data) {
  417. let value = data.educationTypeId == -1 ? -1 : undefined;
  418. data.businessId = value;
  419. data.projectId = value;
  420. },
  421. changeBus(data, projectId) {
  422. data.projectId = projectId;
  423. },
  424. add(index, data) {
  425. data = data ? JSON.parse(JSON.stringify(data)) : this.backItem();
  426. this.itemList.splice(index + 1, 0, data);
  427. },
  428. del(index) {
  429. this.itemList.splice(index, 1);
  430. },
  431. close() {
  432. this.$nextTick(() => {
  433. this.$refs["form"].resetFields();
  434. });
  435. },
  436. backItem() {
  437. return {
  438. projectId: undefined,
  439. itemName: undefined,
  440. itemCategory: undefined,
  441. businessId: undefined,
  442. educationTypeId: undefined,
  443. itemType: undefined,
  444. typeValue: undefined,
  445. minValue: undefined,
  446. maxValue: undefined,
  447. dockStatus: undefined,
  448. dockType: undefined,
  449. dockValue: undefined,
  450. };
  451. },
  452. resetForm() {
  453. this.form = {
  454. itemList: [this.backItem()],
  455. tpId: undefined,
  456. tpName: undefined,
  457. defaultStatus: 0,
  458. tenantId: undefined,
  459. };
  460. },
  461. cb() {
  462. this.$message.success(this.title + "成功");
  463. this.isShow = false;
  464. this.$emit("search");
  465. },
  466. submitForm() {
  467. this.$refs["form"].validate((valid) => {
  468. if (valid) {
  469. let form = JSON.parse(JSON.stringify(this.form));
  470. form.itemList.forEach((ele) => {
  471. if (ele.maxValue === "*") {
  472. ele.maxValue = -1;
  473. }
  474. });
  475. if (this.type === 3 || this.type === 4) {
  476. this.$api
  477. .systemtoporderupdatecost({
  478. costTpVo: this.form,
  479. orderSnList:
  480. this.type === 3 ? [this.tpId] : this.tpId?.split(","),
  481. })
  482. .then(this.cb);
  483. } else if (this.type !== 1) {
  484. addCost(this.form).then(this.cb);
  485. } else {
  486. editCost(this.form).then(this.cb);
  487. }
  488. } else {
  489. return false;
  490. }
  491. });
  492. },
  493. changeMaxValue(prop) {
  494. this.$refs.form.validateField(prop);
  495. },
  496. // 阶梯校验
  497. isHaveIntersect(list) {
  498. const isEmpty = list.some((e) => !e.minValue && !e.maxValue);
  499. if (isEmpty) {
  500. return "非阶梯计价只能存在一个";
  501. }
  502. let maxList = list.filter((e) => e.maxValue === "*");
  503. if (maxList.length > 1) {
  504. return "阶梯计价存在范围冲突";
  505. }
  506. list.sort((a, b) => {
  507. if (a.maxValue == "*") {
  508. return Number.MAX_VALUE;
  509. }
  510. if (b.maxValue == "*") {
  511. return -Number.MAX_VALUE;
  512. }
  513. return a.minValue - b.minValue;
  514. });
  515. for (let i = 0, len = list.length - 1; i < len; i++) {
  516. console.log(i, list);
  517. if (list[i].maxValue >= list[i + 1].minValue) {
  518. return "阶梯计价存在范围冲突";
  519. }
  520. }
  521. return;
  522. },
  523. regValue(data) {
  524. let { maxValue } = data;
  525. let val;
  526. if (maxValue.includes("*")) {
  527. val = "*";
  528. } else {
  529. val = maxValue.replace(/[^0-9]/g, "");
  530. }
  531. data.maxValue = val;
  532. },
  533. },
  534. computed: {
  535. isShow: {
  536. get() {
  537. if (this.dialogVisible) {
  538. this.init();
  539. }
  540. return this.dialogVisible;
  541. },
  542. set(val) {
  543. this.$emit("update:dialogVisible", false);
  544. },
  545. },
  546. title() {
  547. return ["新增", "修改", "复制", "订单成本设置", "批量成本设置"][
  548. this.type
  549. ];
  550. },
  551. itemList() {
  552. return this.form.itemList;
  553. },
  554. },
  555. };
  556. </script>
  557. <style lang="scss" scoped>
  558. /deep/.el-input--medium .el-input__inner {
  559. width: 144px;
  560. }
  561. /deep/ .range {
  562. .el-form-item__content {
  563. width: 170px;
  564. }
  565. .el-input--medium .el-input__inner {
  566. width: 76px;
  567. }
  568. }
  569. /deep/ .ddd {
  570. margin-left: -10px;
  571. .el-input--medium .el-input__inner {
  572. width: 105px;
  573. }
  574. }
  575. .line {
  576. text-align: center;
  577. }
  578. .btns {
  579. height: 36px;
  580. display: flex;
  581. align-items: center;
  582. i {
  583. font-size: 24px;
  584. cursor: pointer;
  585. margin-left: 5px;
  586. }
  587. }
  588. .bop-tip {
  589. background: #fff6f7;
  590. margin: 0 0 20px 10px;
  591. padding: 8px 10px;
  592. i {
  593. font-size: 16px;
  594. color: #e6a23c;
  595. }
  596. }
  597. </style>