index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. <!-- 模板区域 -->
  2. <template>
  3. <div>
  4. <el-dialog v-model="props.ruleConditionVisible" title="规则条件" width="500" draggable @close="close">
  5. <div class="Container flex f-c">
  6. <div class="flex ">
  7. <el-input v-model="attrName" style="margin-right: 20px;" clearable placeholder="搜索"
  8. @keydown.enter="handleEnter" @clear="ruleAttr" />
  9. <el-button @click="ruleAttr" type="primary">查找</el-button>
  10. </div>
  11. <div class="conditionSet flex ">
  12. <div class="tabLeft">
  13. <ul>
  14. <li :class="{ active: item.name == activename }" v-for="(item, index) in typeList" :key="index"
  15. @click="itemclick(item)">{{ item.name }}</li>
  16. </ul>
  17. </div>
  18. <div class="tabRight flex f-c">
  19. <el-checkbox-group v-model="checked.VehicleInformation" @change="change($event, 'VehicleInformation')"
  20. v-for="(item, index) in dataStore.VehicleInformation" :key="index" v-if="activename == '车辆信息'">
  21. <el-checkbox v-model="item.id" :label="item.attrName" :value="item.attrName" size="large" />
  22. </el-checkbox-group>
  23. <el-checkbox-group v-model="checked.VehicleOwnerInformation"
  24. @change="change($event, 'VehicleOwnerInformation')"
  25. v-for="(item, index) in dataStore.VehicleOwnerInformation" :key="index" v-if="activename == '车主信息'">
  26. <el-checkbox v-model="item.id" :label="item.attrName" :value="item.attrName" size="large" />
  27. </el-checkbox-group>
  28. <el-checkbox-group v-model="checked.PolicyholderInformation"
  29. @change="change($event, 'PolicyholderInformation')"
  30. v-for="(item, index) in dataStore.PolicyholderInformation" :key="index" v-if="activename == '投保人信息'">
  31. <el-checkbox v-model="item.id" :label="item.attrName" :value="item.attrName" size="large" />
  32. </el-checkbox-group>
  33. <el-checkbox-group v-model="checked.InsuredInformation" @change="change($event, 'InsuredInformation')"
  34. v-for="(item, index) in dataStore.InsuredInformation" :key="index" v-if="activename == '被保人信息'">
  35. <el-checkbox v-model="item.id" :label="item.attrName" :value="item.attrName" size="large" />
  36. </el-checkbox-group>
  37. <el-checkbox-group v-model="checked.InsuranceInformation" @change="change($event, 'InsuranceInformation')"
  38. v-for="(item, index) in dataStore.InsuranceInformation" :key="index" v-if="activename == '商业险'">
  39. <el-checkbox v-model="item.id" :label="item.attrName" :value="item.attrName" size="large" />
  40. </el-checkbox-group>
  41. <el-checkbox-group v-model="checked.InsuranceCostFactor" @change="change($event, 'InsuranceCostFactor')"
  42. v-for="(item, index) in dataStore.InsuranceCostFactor" :key="index" v-if="activename == '保司费用因子'">
  43. <el-checkbox v-model="item.id" :label="item.attrName" :value="item.attrName" size="large" />
  44. </el-checkbox-group>
  45. </div>
  46. </div>
  47. </div>
  48. <template #footer>
  49. <div class="dialog-footer">
  50. <el-button @click="cancel">取消</el-button>
  51. <el-button type="primary" @click="save">
  52. 保存
  53. </el-button>
  54. </div>
  55. </template>
  56. </el-dialog>
  57. </div>
  58. </template>
  59. <!-- 行为区域 -->
  60. <script lang='ts' setup>
  61. import { ref, reactive } from 'vue'
  62. import api from '@/api'
  63. import { defineProps, defineEmits } from "vue";
  64. const props = defineProps<{
  65. ruleConditionVisible: boolean,
  66. attrIdList?: any,
  67. }>();
  68. const emits = defineEmits(["cancel", 'save']);
  69. const cancel = () => {
  70. emits("cancel")
  71. }
  72. const close = () => {
  73. emits("cancel")
  74. }
  75. watch(props, () => {
  76. if (props.attrIdList && props.attrIdList.length) {
  77. attractivelist.value = props.attrIdList;//获取编辑数据
  78. const matchedid = matchDataByIds(attractivelist.value);//
  79. const matchedinfo = matchDataByInfos(attractivelist.value)
  80. Object.keys(checked).forEach(key => { //复选框回显
  81. checked[key as keyof checkeddata] = matchedid[key] || [];
  82. });
  83. Object.keys(checked).forEach(key => {//条件数据回显
  84. checkeddata[key as keyof checkeddata] = matchedinfo[key] || [];
  85. });
  86. }
  87. })
  88. const save = () => {
  89. const mergedData = [
  90. ...checkeddata.VehicleInformation,
  91. ...checkeddata.VehicleOwnerInformation,
  92. ...checkeddata.PolicyholderInformation,
  93. ...checkeddata.InsuredInformation,
  94. ...checkeddata.InsuranceInformation,
  95. ...checkeddata.InsuranceCostFactor,
  96. ]
  97. emits("save", mergedData)// 返回已选集合
  98. }
  99. const attractivelist = ref();
  100. const attrName = ref();
  101. const activename = ref('车辆信息');
  102. const checked = reactive<checkeddata>({
  103. VehicleInformation: [],//车辆信息
  104. VehicleOwnerInformation: [],//车主信息
  105. PolicyholderInformation: [],//车主信息
  106. InsuredInformation: [],//车主信息
  107. InsuranceInformation: [], //车主信息
  108. InsuranceCostFactor: [],//保司费用因子
  109. })
  110. const licensePlateRegion = ref();//车牌地区
  111. const licensePlateNumber = ref();//车牌号
  112. const matchDataByInfos = (idCollection: any) => {
  113. const matchedData: any = {};
  114. // 遍历 dataStore 的每个键
  115. Object.keys(dataStore).forEach(key => {
  116. // 过滤出匹配的项
  117. matchedData[key as keyof dataStore] = dataStore[key as keyof dataStore].filter((item: any) => {
  118. const match = idCollection.find((idObj: any) => idObj.attrName === item.attrName);
  119. if (match) {
  120. // 如果找到匹配项,将 minArray 和 min 赋值给 item
  121. item.minArray = match.minArray;
  122. item.min = match.min;
  123. return true; // 保留该项
  124. }
  125. return false; // 不保留该项
  126. });
  127. });
  128. return matchedData;
  129. };
  130. const matchDataByIds = (idCollection: any) => {
  131. const matchedData: any = {};
  132. // 提取 idCollection 中的 ID
  133. const ids = idCollection.map((item: any) => item.attrName); // 提取 ID
  134. // 遍历 dataStore 的每个键
  135. Object.keys(dataStore).forEach(key => {
  136. // 过滤出匹配的name回显复选框
  137. matchedData[key as keyof dataStore] = dataStore[key as keyof dataStore].filter(item => ids.includes(item.attrName)).map(item => item.attrName);
  138. });
  139. return matchedData;
  140. };
  141. const typeList = ref([
  142. {
  143. name: "车辆信息",
  144. type: 'VehicleInformation'
  145. },
  146. {
  147. name: "车主信息",
  148. type: 'VehicleOwnerInformation'
  149. },
  150. {
  151. name: "投保人信息",
  152. type: 'PolicyholderInformation'
  153. },
  154. {
  155. name: "被保人信息",
  156. type: 'InsuredInformation'
  157. },
  158. {
  159. name: "商业险",
  160. type: 'InsuranceInformation'
  161. },
  162. {
  163. name: "保司费用因子",
  164. type: 'InsuranceCostFactor'
  165. }
  166. ])
  167. const itemclick = (type: any) => {
  168. activename.value = type.name;
  169. }
  170. const dataStore = reactive<dataStore>({
  171. VehicleInformation: [],//车辆信息
  172. VehicleOwnerInformation: [],//车主信息
  173. PolicyholderInformation: [],//车主信息
  174. InsuredInformation: [],//车主信息
  175. InsuranceInformation: [], //车主信息
  176. InsuranceCostFactor: [],//保司费用因子
  177. })
  178. interface checkeddata {
  179. [key: string]: any[]
  180. }
  181. const checkeddata = reactive<checkeddata>({
  182. VehicleInformation: [],//车辆信息
  183. VehicleOwnerInformation: [],//车主信息
  184. PolicyholderInformation: [],//车主信息
  185. InsuredInformation: [],//车主信息
  186. InsuranceInformation: [], //车主信息
  187. InsuranceCostFactor: [],//保司费用因子
  188. });
  189. //已勾选的规则集合
  190. interface VehicleInformation {
  191. attrName: string,
  192. id: string,
  193. }[]
  194. interface dataStore {
  195. VehicleInformation: VehicleInformation[],
  196. VehicleOwnerInformation: VehicleInformation[],
  197. PolicyholderInformation: VehicleInformation[],
  198. InsuredInformation: VehicleInformation[],
  199. InsuranceInformation: VehicleInformation[],
  200. InsuranceCostFactor: VehicleInformation[],
  201. }
  202. onMounted(() => {
  203. ruleAttr();
  204. regionLicenseRegion('0');//车牌地区
  205. regionLicenseNumber('14');//车牌号
  206. })
  207. const ruleAttr = () => {
  208. api.agreementApi.ruleAttrGroup({ attrName: attrName.value }).then((res: any) => {
  209. if (res.code == '200') {
  210. dataStore.VehicleInformation = processArray(res.data.VehicleInformation);
  211. dataStore.VehicleOwnerInformation = processArray(res.data.VehicleOwnerInformation);
  212. dataStore.PolicyholderInformation = processArray(res.data.PolicyholderInformation);
  213. dataStore.InsuredInformation = processArray(res.data.InsuredInformation);
  214. dataStore.InsuranceInformation = processArray(res.data.InsuranceInformation);
  215. dataStore.InsuranceCostFactor = processArray(res.data.InsuranceCostFactor);
  216. } else {
  217. }
  218. });
  219. }
  220. //选择事件集中处理
  221. type title = keyof typeof dataStore;
  222. const change = (value: any, title: title) => {
  223. // 使用动态属性访问
  224. let arrayToUpdate = dataStore[title];//获取对应类型数组
  225. if (arrayToUpdate) {
  226. checkeddata[title] = [];//默认清空
  227. arrayToUpdate = arrayToUpdate.map((val) => {
  228. value.map((item: string) => {
  229. if (val.attrName == item) {
  230. checkeddata[title].push(val)//匹配相同值选中数据存入
  231. }
  232. })
  233. return val;
  234. });
  235. } else {
  236. }
  237. };
  238. // 遍历并处理每个数组
  239. const processArray = (array: any[]) => {
  240. return array.map((val) => {
  241. switch (val.attrType) {
  242. case 'inputNumber':
  243. case 'datetime':
  244. if (!val.operator) {
  245. val.operator = '1'; // 设置默认值
  246. }
  247. break;
  248. default:
  249. break;
  250. }
  251. if (val.attrCode == 'LicenseNo') {
  252. val.dictLabal = licensePlateNumber.value;
  253. }
  254. if (val.attrCode == 'LicenseArea') {
  255. val.dictLabal = licensePlateRegion.value;
  256. }
  257. val.isCheck = 0;
  258. return val;
  259. });
  260. };
  261. const handleEnter = (e: any) => {
  262. if (e.keyCode == 13 || e.keyCode == 108) {
  263. ruleAttr();
  264. }
  265. }
  266. const regionLicenseRegion = (value: string) => {
  267. api.agreementApi.getAreaLicense(value).then((res: any) => {
  268. if (res.code == '200') {
  269. let data: any = [];
  270. res.data.map((val: any) => {
  271. data.push({
  272. code: val.areaNumber,
  273. name: val.license,
  274. })
  275. return val;
  276. })
  277. licensePlateRegion.value = data;
  278. } else {
  279. }
  280. });
  281. }
  282. const regionLicenseNumber = (value: string) => {
  283. api.agreementApi.getAreaLicense(value).then((res: any) => {
  284. if (res.code == '200') {
  285. let data: any = [];
  286. res.data.map((val: any) => {
  287. data.push({
  288. code: val.areaNumber,
  289. name: val.license,
  290. })
  291. return val;
  292. })
  293. licensePlateNumber.value = data;
  294. } else {
  295. }
  296. });
  297. }
  298. </script>
  299. <!-- 样式区域 -->
  300. <style lang='scss' scoped>
  301. .conditionSet {
  302. padding: 20px 0;
  303. margin-top: 10px;
  304. .tabLeft {
  305. width: 100px;
  306. ul {
  307. padding: 0;
  308. margin: 0;
  309. list-style: none;
  310. border-right: 1px solid #dcdfe6;
  311. li {
  312. height: 40px;
  313. font-weight: 500;
  314. line-height: 40px;
  315. text-align: center;
  316. cursor: pointer;
  317. }
  318. li:hover {
  319. color: #0083ff;
  320. background: #f4faff;
  321. transition: 0.3s;
  322. }
  323. }
  324. }
  325. .active {
  326. color: #0083ff;
  327. background: #f4faff;
  328. }
  329. .tabRight {
  330. flex: 1;
  331. max-height: 300px;
  332. padding: 0 20px;
  333. overflow-y: auto;
  334. }
  335. }
  336. </style>