auto-settlement-config.ts 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. import { Component, OnInit, signal } from '@angular/core';
  2. import { CommonModule } from '@angular/common';
  3. import { FormsModule } from '@angular/forms';
  4. import { MatCardModule } from '@angular/material/card';
  5. import { MatButtonModule } from '@angular/material/button';
  6. import { MatIconModule } from '@angular/material/icon';
  7. import { MatExpansionModule } from '@angular/material/expansion';
  8. import { MatSelectModule } from '@angular/material/select';
  9. import { MatInputModule } from '@angular/material/input';
  10. import { MatCheckboxModule } from '@angular/material/checkbox';
  11. import { MatSlideToggleModule } from '@angular/material/slide-toggle';
  12. import { MatDialogModule, MatDialog } from '@angular/material/dialog';
  13. import { AutoSettlementService, AutoSettlementRule, SettlementCondition, SettlementAction } from '../../../services/auto-settlement.service';
  14. @Component({
  15. selector: 'app-auto-settlement-config',
  16. standalone: true,
  17. imports: [
  18. CommonModule,
  19. FormsModule,
  20. MatCardModule,
  21. MatButtonModule,
  22. MatIconModule,
  23. MatExpansionModule,
  24. MatSelectModule,
  25. MatInputModule,
  26. MatCheckboxModule,
  27. MatSlideToggleModule,
  28. MatDialogModule
  29. ],
  30. templateUrl: './auto-settlement-config.html',
  31. styleUrls: ['./auto-settlement-config.scss']
  32. })
  33. export class AutoSettlementConfigComponent implements OnInit {
  34. rules = signal<AutoSettlementRule[]>([]);
  35. expandedPanels = signal<Set<string>>(new Set());
  36. isAddingNew = signal(false);
  37. // 条件类型选项
  38. conditionTypes = [
  39. { value: 'amountRange', label: '金额范围' },
  40. { value: 'overdueDays', label: '逾期天数' },
  41. { value: 'customerTier', label: '客户层级' },
  42. { value: 'projectType', label: '项目类型' },
  43. { value: 'paymentMethod', label: '支付方式' }
  44. ];
  45. // 操作符选项
  46. operators = [
  47. { value: 'equals', label: '等于' },
  48. { value: 'greaterThan', label: '大于' },
  49. { value: 'lessThan', label: '小于' },
  50. { value: 'between', label: '介于' },
  51. { value: 'contains', label: '包含' }
  52. ];
  53. // 动作类型选项
  54. actionTypes = [
  55. { value: 'sendReminder', label: '发送提醒' },
  56. { value: 'applyDiscount', label: '应用折扣' },
  57. { value: 'extendDueDate', label: '延长期限' },
  58. { value: 'autoConfirm', label: '自动确认' },
  59. { value: 'notifyManager', label: '通知经理' }
  60. ];
  61. // 新规则模板
  62. newRule: AutoSettlementRule = {
  63. id: '',
  64. name: '',
  65. enabled: true,
  66. priority: 5,
  67. conditions: [],
  68. actions: [],
  69. description: ''
  70. };
  71. constructor(private autoSettlementService: AutoSettlementService) {}
  72. ngOnInit() {
  73. this.loadRules();
  74. }
  75. // 加载规则
  76. loadRules() {
  77. this.autoSettlementService.getRules().subscribe(rules => {
  78. this.rules.set(rules);
  79. });
  80. }
  81. // 切换面板展开状态
  82. togglePanel(ruleId: string) {
  83. const panels = new Set(this.expandedPanels());
  84. if (panels.has(ruleId)) {
  85. panels.delete(ruleId);
  86. } else {
  87. panels.add(ruleId);
  88. }
  89. this.expandedPanels.set(panels);
  90. }
  91. // 添加新条件
  92. addCondition(rule: AutoSettlementRule) {
  93. const newCondition: SettlementCondition = {
  94. type: 'amountRange',
  95. operator: 'greaterThan',
  96. value: 0
  97. };
  98. rule.conditions.push(newCondition);
  99. }
  100. // 删除条件
  101. removeCondition(rule: AutoSettlementRule, index: number) {
  102. rule.conditions.splice(index, 1);
  103. }
  104. // 添加新动作
  105. addAction(rule: AutoSettlementRule) {
  106. const newAction: SettlementAction = {
  107. type: 'sendReminder',
  108. params: {}
  109. };
  110. rule.actions.push(newAction);
  111. }
  112. // 删除动作
  113. removeAction(rule: AutoSettlementRule, index: number) {
  114. rule.actions.splice(index, 1);
  115. }
  116. // 保存规则
  117. saveRule(rule: AutoSettlementRule) {
  118. if (rule.id) {
  119. this.autoSettlementService.updateRule(rule.id, rule);
  120. } else {
  121. rule.id = `rule-${Date.now()}`;
  122. this.autoSettlementService.addRule(rule);
  123. }
  124. this.cancelAddNew();
  125. }
  126. // 删除规则
  127. async deleteRule(ruleId: string): Promise<void> {
  128. const ok = await window?.fmode?.confirm('确定要删除这条规则吗?');
  129. if (ok) {
  130. this.autoSettlementService.deleteRule(ruleId);
  131. this.loadRules();
  132. }
  133. }
  134. // 启用/禁用规则
  135. toggleRule(rule: AutoSettlementRule) {
  136. rule.enabled = !rule.enabled;
  137. this.autoSettlementService.updateRule(rule.id, { enabled: rule.enabled });
  138. }
  139. // 开始添加新规则
  140. startAddNew() {
  141. this.isAddingNew.set(true);
  142. this.newRule = {
  143. id: '',
  144. name: '',
  145. enabled: true,
  146. priority: 5,
  147. conditions: [],
  148. actions: [],
  149. description: ''
  150. };
  151. }
  152. // 取消添加新规则
  153. cancelAddNew() {
  154. this.isAddingNew.set(false);
  155. }
  156. // 获取条件操作符选项
  157. getOperatorOptions(conditionType: string) {
  158. switch (conditionType) {
  159. case 'amountRange':
  160. case 'overdueDays':
  161. return this.operators.filter(op =>
  162. ['equals', 'greaterThan', 'lessThan', 'between'].includes(op.value)
  163. );
  164. case 'customerTier':
  165. case 'projectType':
  166. case 'paymentMethod':
  167. return this.operators.filter(op =>
  168. ['equals', 'contains'].includes(op.value)
  169. );
  170. default:
  171. return this.operators;
  172. }
  173. }
  174. // 获取动作参数配置
  175. getActionParamsConfig(actionType: string) {
  176. switch (actionType) {
  177. case 'sendReminder':
  178. return {
  179. channels: ['wechat', 'sms', 'email', 'system'],
  180. frequency: ['immediate', 'daily', 'weekly']
  181. };
  182. case 'applyDiscount':
  183. return {
  184. type: ['percentage', 'fixed'],
  185. maxAmount: 1000
  186. };
  187. case 'extendDueDate':
  188. return {
  189. days: 7
  190. };
  191. case 'autoConfirm':
  192. return {
  193. immediate: true
  194. };
  195. case 'notifyManager':
  196. return {
  197. threshold: 10000
  198. };
  199. default:
  200. return {};
  201. }
  202. }
  203. // 格式化条件显示
  204. formatCondition(condition: SettlementCondition): string {
  205. switch (condition.type) {
  206. case 'amountRange':
  207. return `金额 ${this.getOperatorLabel(condition.operator)} ${condition.value}`;
  208. case 'overdueDays':
  209. return `逾期天数 ${this.getOperatorLabel(condition.operator)} ${condition.value}`;
  210. case 'customerTier':
  211. return `客户层级 ${this.getOperatorLabel(condition.operator)} ${condition.value}`;
  212. default:
  213. return `${condition.type} ${condition.operator} ${condition.value}`;
  214. }
  215. }
  216. // 格式化动作显示
  217. formatAction(action: SettlementAction): string {
  218. switch (action.type) {
  219. case 'sendReminder':
  220. return '发送提醒';
  221. case 'applyDiscount':
  222. return '应用折扣';
  223. case 'extendDueDate':
  224. return '延长期限';
  225. case 'autoConfirm':
  226. return '自动确认';
  227. case 'notifyManager':
  228. return '通知经理';
  229. default:
  230. return action.type;
  231. }
  232. }
  233. // 获取操作符标签
  234. private getOperatorLabel(operator: string): string {
  235. const op = this.operators.find(o => o.value === operator);
  236. return op ? op.label : operator;
  237. }
  238. }