CommissionRule.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. <!-- 模板区域 -->
  2. <template>
  3. <div class="p-2" style="padding-bottom: 100px;box-sizing: border-box;">
  4. <h5>佣金规则</h5>
  5. <el-form ref="formRef" :model="from" label-width="150px" size="small" :rules="rules" style="width: 1000px;">
  6. <el-form-item label="创始人佣金比例" prop="originator">
  7. <el-input v-model="from.originator"></el-input>
  8. </el-form-item>
  9. <el-form-item label="管理人佣金比例">
  10. <div class="flex f-c ">
  11. <div class="flex ">
  12. <el-form-item label="管理人与合伙人共享" prop="administrator.sharedRatio">
  13. <el-input v-model="from.administrator.sharedRatio"></el-input>
  14. </el-form-item>
  15. <el-form-item label="管理人默认佣金比例" class="ml-1" prop="administrator.defaultRatio">
  16. <el-input v-model="from.administrator.defaultRatio"></el-input>
  17. </el-form-item>
  18. </div>
  19. <el-form-item label="佣金有效期" class="m-top-10 spacing " prop="administrator.validityPeriod">
  20. <el-radio-group v-model="from.administrator.validityPeriod" class="flex f-c ">
  21. <el-radio label="1">不限期</el-radio>
  22. <el-radio label="2" class="flex a-c">
  23. <span class="mr-2">固定天数</span>
  24. <el-form-item v-if="from.administrator.validityPeriod === '2'" label=" 成为该等级后,限期"
  25. prop="administrator.fixedDays">
  26. <el-input class="width" v-model="from.administrator.fixedDays" size="small" style="margin: 0 5px;"
  27. placeholder="请输入1~365的正整数" :maxlength="3">
  28. <template slot="append">天</template>
  29. </el-input>
  30. </el-form-item>
  31. </el-radio>
  32. <el-radio label="3" class="flex a-c">
  33. <span>固定日期</span>
  34. <div class="flex a-c" v-if="from.administrator.validityPeriod === '3'">
  35. <el-form-item label="成为该等级后,限期" label-width="200px" prop="administrator.startDate">
  36. <el-date-picker class="width" v-model="from.administrator.startDate"
  37. :disabled="['1', '2'].includes(from.administrator.validityPeriod)" type="date" placeholder="选择日期"
  38. value-format="yyyy-MM-dd">
  39. </el-date-picker>
  40. </el-form-item>
  41. <span style="margin: 0 5px;">至</span>
  42. <el-form-item prop="administrator.endDate">
  43. <el-date-picker class="width" v-model="from.administrator.endDate"
  44. :disabled="['1', '2'].includes(from.administrator.validityPeriod)" type="date" placeholder="选择日期"
  45. value-format="yyyy-MM-dd">
  46. </el-date-picker>
  47. </el-form-item>
  48. </div>
  49. </el-radio>
  50. </el-radio-group>
  51. </el-form-item>
  52. <div class="row flex f-c " v-for="(ruleitem, ruleindex) in from.administrator.rulesRatioList"
  53. :key="ruleindex">
  54. <div class="flex j-s a-c">
  55. <span>合伙人佣金-阶梯{{ ruleindex + 1 }}</span>
  56. <span v-if="ruleindex != 0" class="cursor" @click="del('administrator', ruleindex)">删除</span>
  57. </div>
  58. <div class="flex f-c ">
  59. <div class="flex a-c mb-2" v-for="(item, index) in ruleitem.partnerRatioList" :key="index">
  60. <!-- 复选框 -->
  61. <el-checkbox v-if="index==0" v-model="item.ry"
  62. @change="handleCheckboxChange(ruleindex, index, 'administrator')"></el-checkbox>
  63. <el-checkbox v-if="index==1" v-model="item.bf"
  64. @change="handleCheckboxChange(ruleindex, index, 'administrator')"></el-checkbox>
  65. <el-checkbox v-if="index==2" v-model="item.gr"
  66. @change="handleCheckboxChange(ruleindex, index, 'administrator')"></el-checkbox>
  67. <span style="margin: 0 10px;">{{ index == 0 ?
  68. `人员考核&nbsp;&nbsp;&nbsp;&nbsp;邀请工作室达` : index == 1 ? `保费考核&nbsp;&nbsp;&nbsp;&nbsp;下属工作室出单保费` :
  69. `保费考核&nbsp;&nbsp;&nbsp;&nbsp;自己的出单费用`
  70. }}</span>
  71. <!-- 输入框 -->
  72. <el-form-item :prop="`administrator.rulesRatioList.${ruleindex}.partnerRatioList.${index}.min`"
  73. :rules="getRules(ruleindex, index, 'min', 'administrator')">
  74. <el-input-number v-model="item.min" size="small" controls-position="right" :min="1"
  75. :max="index ? 100000000 : 10000" :precision="index ? 2 : 0"
  76. style="margin: 0 5px;width: 200px;"></el-input-number>
  77. <span>{{ index ? '元' : '人' }}</span>
  78. </el-form-item>
  79. </div>
  80. <div class="flex a-c">
  81. 以上条件
  82. <el-form-item :prop="`administrator.rulesRatioList.${ruleindex}.allSatisfied`"
  83. :rules="rules.allSatisfied">
  84. <el-select v-model="ruleitem.allSatisfied" placeholder="请选择">
  85. <el-option label="全部满足" :value="1"></el-option>
  86. <el-option label="满足任意一条" :value="2"></el-option>
  87. </el-select>
  88. </el-form-item>
  89. 合伙人获取共享佣金的
  90. <el-form-item :prop="`administrator.rulesRatioList.${ruleindex}.kickback`" :rules="rules.kickback">
  91. <el-input class="width" v-model="ruleitem.kickback" size="small" style="margin: 0 5px;"
  92. placeholder="请输入">
  93. <template slot="append">%</template>
  94. </el-input>
  95. </el-form-item>
  96. </div>
  97. </div>
  98. </div>
  99. <span class="cursor" v-if="from.administrator.rulesRatioList && from.administrator.rulesRatioList.length < 5"
  100. @click="rulesAdd('administrator')">添加</span>
  101. </div>
  102. </el-form-item>
  103. <el-form-item label="合伙人佣金比例">
  104. <div class="flex f-c ">
  105. <div class="flex ">
  106. <el-form-item label="合伙人与工作室共享" prop="partner.sharedRatio">
  107. <el-input v-model="from.partner.sharedRatio"></el-input>
  108. </el-form-item>
  109. <el-form-item label="合伙人默认佣金比例" class="ml-1" prop="partner.defaultRatio">
  110. <el-input v-model="from.partner.defaultRatio"></el-input>
  111. </el-form-item>
  112. </div>
  113. <el-form-item label="佣金有效期" class="m-top-10 spacing " prop="partner.validityPeriod">
  114. <el-radio-group v-model="from.partner.validityPeriod" class="flex f-c ">
  115. <el-radio label="1">不限期</el-radio>
  116. <el-radio label="2" class="flex a-c">
  117. <span class="mr-2">固定天数</span>
  118. <el-form-item v-if="from.partner.validityPeriod === '2'" label=" 成为该等级后,限期" prop="partner.fixedDays">
  119. <el-input class="width" v-model="from.partner.fixedDays" type="number" size="small"
  120. style="margin: 0 5px;" placeholder="请输入1~365的正整数" :maxlength="3">
  121. <template slot="append">天</template>
  122. </el-input>
  123. </el-form-item>
  124. </el-radio>
  125. <el-radio label="3" class="flex a-c">
  126. <span>固定日期</span>
  127. <div class="flex a-c" v-if="from.partner.validityPeriod === '3'">
  128. <el-form-item label="成为该等级后,限期" label-width="200px" prop="partner.startDate">
  129. <el-date-picker class="width" v-model="from.partner.startDate"
  130. :disabled="['1', '2'].includes(from.partner.validityPeriod)" type="date" placeholder="选择日期"
  131. value-format="yyyy-MM-dd">
  132. </el-date-picker>
  133. </el-form-item>
  134. <span style="margin: 0 5px;">至</span>
  135. <el-form-item prop="partner.endDate">
  136. <el-date-picker class="width" v-model="from.partner.endDate"
  137. :disabled="['1', '2'].includes(from.partner.validityPeriod)" type="date" placeholder="选择日期"
  138. value-format="yyyy-MM-dd">
  139. </el-date-picker>
  140. </el-form-item>
  141. </div>
  142. </el-radio>
  143. </el-radio-group>
  144. </el-form-item>
  145. <div class="row flex f-c " v-for="(ruleitem, ruleindex) in from.partner.rulesRatioList" :key="ruleindex">
  146. <div class="flex j-s a-c">
  147. <span>工作室佣金-阶梯{{ ruleindex + 1 }}</span>
  148. <span v-if="ruleindex != 0" class="cursor" @click="del('partner', ruleindex)">删除</span>
  149. </div>
  150. <div class="flex f-c ">
  151. <div class="flex a-c mb-2" v-for="(item, index) in ruleitem.partnerRatioList" :key="index">
  152. <!-- 复选框 -->
  153. <el-checkbox v-if="index==0" v-model="item.ry"
  154. @change="handleCheckboxChange(ruleindex, index, 'partner')"></el-checkbox>
  155. <el-checkbox v-if="index==1" v-model="item.bf"
  156. @change="handleCheckboxChange(ruleindex, index, 'partner')"></el-checkbox>
  157. <el-checkbox v-if="index==2" v-model="item.gr"
  158. @change="handleCheckboxChange(ruleindex, index, 'partner')"></el-checkbox>
  159. <span style="margin: 0 10px;">{{ index == 0 ?
  160. `人员考核&nbsp;&nbsp;&nbsp;&nbsp;邀请团队达` : index == 1 ? `保费考核&nbsp;&nbsp;&nbsp;&nbsp;下属团队出单保费` : `保费考核&nbsp;&nbsp;&nbsp;&nbsp;自己的出单费用`
  161. }}</span>
  162. <!-- 输入框 -->
  163. <el-form-item :prop="`partner.rulesRatioList.${ruleindex}.partnerRatioList.${index}.min`"
  164. :rules="getRules(ruleindex, index, 'min', 'partner')">
  165. <el-input-number v-model="item.min" size="small" controls-position="right" :min="1"
  166. :max="index ? 100000000 : 10000" :precision="index ? 2 : 0"
  167. style="margin: 0 5px;width: 200px;"></el-input-number>
  168. <span>{{ index ? '元' : '人' }}</span>
  169. </el-form-item>
  170. </div>
  171. <div class="flex a-c">
  172. 以上条件
  173. <el-form-item :prop="`partner.rulesRatioList.${ruleindex}.allSatisfied`" :rules="rules.allSatisfied">
  174. <el-select v-model="ruleitem.allSatisfied" placeholder="请选择">
  175. <el-option label="全部满足" :value="1"></el-option>
  176. <el-option label="满足任意一条" :value="2"></el-option>
  177. </el-select>
  178. </el-form-item>
  179. 工作室获取共享佣金的
  180. <el-form-item :prop="`partner.rulesRatioList.${ruleindex}.kickback`" :rules="rules.kickback">
  181. <el-input class="width" v-model="ruleitem.kickback" size="small" style="margin: 0 5px;"
  182. placeholder="请输入">
  183. <template slot="append">%</template>
  184. </el-input>
  185. </el-form-item>
  186. </div>
  187. </div>
  188. </div>
  189. <span class="cursor" v-if="from.partner.rulesRatioList && from.partner.rulesRatioList.length < 5"
  190. @click="rulesAdd('partner')">添加</span>
  191. </div>
  192. </el-form-item>
  193. </el-form>
  194. <div class="footer flex a-c j-c">
  195. <el-button type="primary" size="small" @click="save">保存</el-button>
  196. </div>
  197. </div>
  198. </template>
  199. <!-- 行为区域 -->
  200. <script>
  201. export default {
  202. // 数据存放区域
  203. data() {
  204. return {
  205. from: {
  206. administrator: {},
  207. partner: {},
  208. },
  209. rules: {
  210. originator: [
  211. { required: true, message: '请输入创始人佣金比例', trigger: 'blur' },
  212. ],
  213. 'administrator.sharedRatio': [
  214. { required: true, message: '请输入管理人与合伙人共享比例', trigger: 'blur' }
  215. ],
  216. 'administrator.defaultRatio': [
  217. { required: true, message: '请输入管理人默认佣金比例', trigger: 'blur' }
  218. ],
  219. 'administrator.validityPeriod': [
  220. { required: true, message: '请选择佣金有效期', trigger: 'change' }
  221. ],
  222. 'administrator.fixedDays': [
  223. { required: true, message: '请输入固定天数', trigger: 'blur' },
  224. { type: 'number', message: '必须为数字', trigger: 'blur', transform: (value) => Number(value) },
  225. {
  226. validator: (rule, value, callback) => {
  227. if (value < 1 || value > 365 || !Number.isInteger(value)) {
  228. callback(new Error('必须是1-365的整数'));
  229. } else {
  230. callback();
  231. }
  232. },
  233. trigger: 'blur'
  234. }
  235. ],
  236. 'administrator.startDate': [
  237. { required: true, message: '请选择开始日期', trigger: 'change' }
  238. ],
  239. 'administrator.endDate': [
  240. { required: true, message: '请选择结束日期', trigger: 'change' }
  241. ],
  242. 'partner.sharedRatio': [
  243. { required: true, message: '请输入管理人与合伙人共享比例', trigger: 'blur' }
  244. ],
  245. 'partner.defaultRatio': [
  246. { required: true, message: '请输入管理人默认佣金比例', trigger: 'blur' }
  247. ],
  248. 'partner.validityPeriod': [
  249. { required: true, message: '请选择佣金有效期', trigger: 'change' }
  250. ],
  251. 'partner.fixedDays': [
  252. { required: true, message: '请输入固定天数', trigger: 'blur' },
  253. { type: 'number', message: '必须为数字', trigger: 'blur', transform: (value) => Number(value) },
  254. {
  255. validator: (rule, value, callback) => {
  256. if (value < 1 || value > 365 || !Number.isInteger(value)) {
  257. callback(new Error('必须是1-365的整数'));
  258. } else {
  259. callback();
  260. }
  261. },
  262. trigger: 'blur'
  263. }
  264. ],
  265. 'partner.startDate': [
  266. { required: true, message: '请选择开始日期', trigger: 'change' }
  267. ],
  268. 'partner.endDate': [
  269. { required: true, message: '请选择结束日期', trigger: 'change' }
  270. ],
  271. min: [
  272. { required: true, message: '请输入最小值', trigger: 'blur' },
  273. { type: 'number', message: '必须为数字', trigger: 'blur', transform: (value) => Number(value) }
  274. ],
  275. allSatisfied: [
  276. { required: true, message: '请选择条件', trigger: 'change' }
  277. ],
  278. kickback: [
  279. { required: true, message: '请输入佣金比例', trigger: 'blur' },
  280. { type: 'number', message: '必须为数字', trigger: 'blur', transform: (value) => Number(value) }
  281. ]
  282. }
  283. }
  284. },
  285. // 生命周期函数
  286. created() {
  287. this.Query();
  288. },
  289. mounted() {
  290. },
  291. // 方法函数
  292. methods: {
  293. // 处理复选框变化
  294. handleCheckboxChange(ruleindex, index, typename) {
  295. // 手动触发表单校验
  296. this.$refs.formRef.validateField([
  297. `${typename}.rulesRatioList.${ruleindex}.partnerRatioList.${index}.min`,
  298. ]);
  299. },
  300. // 动态获取校验规则
  301. getRules(ruleindex, index, field, typename) {
  302. const item = this.from[typename].rulesRatioList[ruleindex].partnerRatioList[index];
  303. const isRequired = index == 0 ? item.ry : index == 1 ? item.bf : item.gr; // 根据复选框决定是否必填
  304. // 动态生成规则数组
  305. const rules = [];
  306. // 如果必填,添加 required 规则
  307. if (isRequired) {
  308. rules.push({
  309. required: true,
  310. message: `请输入${field === 'min' ? '最小值' : '最大值'}`,
  311. trigger: 'blur',
  312. });
  313. }
  314. // 如果有值,则校验是否为数字
  315. rules.push({
  316. validator: (rule, value, callback) => {
  317. if (value !== null && value !== undefined && value !== '') {
  318. if (isNaN(Number(value))) {
  319. callback(new Error('必须为数字'));
  320. } else {
  321. callback();
  322. }
  323. } else {
  324. callback();
  325. }
  326. },
  327. trigger: 'blur',
  328. });
  329. return rules;
  330. },
  331. Query() {
  332. this.$api.retail.commissionQuery().then((res) => {
  333. if (res.code == '200') {
  334. this.from = Object.assign({}, res.data);
  335. } else {
  336. this.$message({
  337. type: 'error',
  338. message: res.msg,
  339. });
  340. }
  341. });
  342. },
  343. rulesAdd(Name) {
  344. const info = this.from[Name].rulesRatioList[this.from[Name].rulesRatioList.length - 1]
  345. // console.log(this.from[Name].rulesRatioList[this.from[Name].rulesRatioList.length - 1])
  346. if (info.partnerRatioList[0].min) {
  347. this.from[Name].rulesRatioList.push({
  348. allSatisfied: "",
  349. kickback: "",
  350. partnerRatioList: [
  351. {
  352. bf: false,
  353. ry: false,
  354. gr: false,
  355. min: info.partnerRatioList[0].min + 1,
  356. },
  357. {
  358. bf: false,
  359. ry: false,
  360. gr: false,
  361. min: info.partnerRatioList[1].min + 1,
  362. },
  363. {
  364. bf: false,
  365. ry: false,
  366. gr: false,
  367. min: info.partnerRatioList[1].min + 1,
  368. }
  369. ]
  370. })
  371. } else {
  372. this.$message({
  373. type: 'error',
  374. message: '请先将最小值补充完整',
  375. });
  376. }
  377. },
  378. del(Name, index) {
  379. this.from[Name].rulesRatioList.splice(index, 1)
  380. },
  381. save() {
  382. this.$refs.formRef.validate((valid) => {
  383. if (valid) {
  384. this.$api.retail.commissionsave(this.from).then((res) => {
  385. if (res.code == '200') {
  386. this.$message({
  387. type: 'success',
  388. message: res.msg,
  389. });
  390. } else {
  391. this.$message({
  392. type: 'error',
  393. message: res.msg,
  394. });
  395. }
  396. });
  397. } else {
  398. console.log('校验失败');
  399. }
  400. });
  401. }
  402. },
  403. // 计算属性
  404. computed: {
  405. propfixedDays() {
  406. console.log(this.from.administrator.validityPeriod)
  407. return this.from.administrator.validityPeriod == '2' ? 'administrator.fixedDays' : '';
  408. }
  409. }
  410. }
  411. </script>
  412. <!-- 样式区域 -->
  413. <style lang='scss' scoped>
  414. .spacing {
  415. .el-radio {
  416. margin: 10px 0;
  417. }
  418. }
  419. .cursor {
  420. color: #2680F0;
  421. cursor: pointer;
  422. }
  423. .width {
  424. width: 220px;
  425. }
  426. .row {
  427. background-color: #f2f2f2;
  428. padding: 6px 20px;
  429. box-sizing: border-box;
  430. width: 100%;
  431. border-radius: 5px;
  432. margin-bottom: 10px;
  433. }
  434. .footer {
  435. position: fixed;
  436. bottom: 0;
  437. right: 0;
  438. background-color: #fff;
  439. z-index: 9;
  440. padding: 20px;
  441. width: 100%;
  442. box-sizing: border-box;
  443. box-shadow: 0 0 1px 0 #ccc;
  444. transition: all 0.1s, box-shadow 0.5s;
  445. }
  446. /deep/ .el-form-item__content .el-input-group {
  447. vertical-align: unset;
  448. }
  449. /deep/ {
  450. .el-radio,
  451. .el-radio__label {
  452. display: flex;
  453. align-items: center;
  454. }
  455. .el-form {
  456. .el-input {
  457. width: 200px;
  458. }
  459. .el-form-item .el-form-item {
  460. margin-bottom: 0;
  461. }
  462. }
  463. }
  464. </style>