ConfigSection.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <template>
  2. <div class="config-group">
  3. <div class="group-header">
  4. <div class="group-title">{{ partName }}</div>
  5. </div>
  6. <div v-for="(item, index) in selectedConfigItems" :key="item.pzid" class="config-row">
  7. <el-select
  8. v-model="item.pzid"
  9. placeholder="选择选配项"
  10. size="small"
  11. class="select-config-item"
  12. @change="onConfigItemChange(item)"
  13. >
  14. <el-option v-for="option in configItemOptions" :key="option.pzid" :label="option.pzname" :value="option.pzid" />
  15. </el-select>
  16. <!-- 配置值选择 -->
  17. <el-select
  18. v-model="item.selectedValue"
  19. placeholder="选择选配值"
  20. size="small"
  21. class="select-config-value"
  22. value-key="namemx"
  23. @change="value => onConfigValueChange(item, value)"
  24. >
  25. <el-option v-for="opt in valueListByPzid(item.pzid)" :key="opt.printid" :label="opt.namemx" :value="opt" />
  26. </el-select>
  27. <i class="iconfont icontrash-01 delete-icon" @click="removeConfigItem(index)" title="删除选配项" />
  28. </div>
  29. <div class="add-config-btn">
  30. <el-button type="primary" icon="el-icon-plus" size="small" @click="addConfigItem"> 添加选配项 </el-button>
  31. </div>
  32. </div>
  33. </template>
  34. <script setup lang="ts">
  35. import { ref, PropType, watch } from "vue";
  36. import { ElMessage } from "element-plus";
  37. interface ConfigValue {
  38. printid: number;
  39. namemx: string;
  40. }
  41. interface ConfigItemOption {
  42. pzid: number;
  43. pzname: string;
  44. }
  45. interface SelectedConfigItem {
  46. pzid: number;
  47. selectedId: number;
  48. selectedValue?: string;
  49. }
  50. const props = defineProps({
  51. partName: { type: String, required: true },
  52. selectedConfigItems: { type: Array as PropType<SelectedConfigItem[]>, required: true },
  53. configItemOptions: { type: Array as PropType<ConfigItemOption[]>, required: true },
  54. configValueOptionsMap: { type: Object as PropType<Record<number, ConfigValue[]>>, required: true }
  55. });
  56. const emit = defineEmits(["update:selectedConfigItems"]);
  57. const valueListByPzid = (pzid: number) => {
  58. return props.configValueOptionsMap[pzid] || [];
  59. };
  60. const onConfigItemChange = (item: SelectedConfigItem) => {
  61. const options = valueListByPzid(item.pzid);
  62. item.selectedId = options.length > 0 ? options[0].printid : 0;
  63. item.selectedValue = options.length > 0 ? options[0].namemx : "";
  64. };
  65. const onConfigValueChange = (item: SelectedConfigItem, value: any) => {
  66. item.selectedId = value.printid;
  67. item.selectedValue = value.namemx;
  68. };
  69. const removeConfigItem = (index: number) => {
  70. const newList = [...props.selectedConfigItems];
  71. newList.splice(index, 1);
  72. emit("update:selectedConfigItems", newList);
  73. };
  74. const addConfigItem = () => {
  75. if (props.configItemOptions.length === 0) {
  76. ElMessage.error(`${props.partName}没有设置相关选配项`);
  77. return;
  78. }
  79. const defaultPzid = props.configItemOptions[0].pzid;
  80. const defaultValues = props.configValueOptionsMap[defaultPzid] || [];
  81. const newItem: SelectedConfigItem = {
  82. pzid: defaultPzid,
  83. selectedId: defaultValues.length > 0 ? defaultValues[0].printid : 0,
  84. selectedValue: defaultValues.length > 0 ? defaultValues[0].namemx : ""
  85. };
  86. emit("update:selectedConfigItems", [...props.selectedConfigItems, newItem]);
  87. };
  88. </script>
  89. <style scoped lang="scss">
  90. .config-section-card {
  91. margin-bottom: 16px;
  92. }
  93. .card-header {
  94. font-weight: bold;
  95. font-size: 16px;
  96. margin-bottom: 12px;
  97. }
  98. .config-row {
  99. display: flex;
  100. align-items: center;
  101. gap: 12px;
  102. margin-bottom: 8px;
  103. width: 100%;
  104. }
  105. .select-config-item {
  106. flex: 1;
  107. }
  108. .select-config-value {
  109. flex: 3;
  110. }
  111. /* 删除图标样式 */
  112. .delete-icon {
  113. cursor: pointer;
  114. font-size: 18px;
  115. user-select: none;
  116. }
  117. /* 添加选配项按钮左对齐 */
  118. .add-config-btn {
  119. margin-top: 12px;
  120. text-align: left;
  121. }
  122. .config-group {
  123. background: #fafafa;
  124. border: 1px solid #e4e7ed;
  125. border-radius: 4px;
  126. margin-bottom: 15px;
  127. padding: 10px;
  128. position: relative;
  129. }
  130. .group-header {
  131. display: flex;
  132. justify-content: space-between;
  133. align-items: center;
  134. margin-bottom: 15px;
  135. padding-bottom: 10px;
  136. border-bottom: 1px dashed #ebeef5;
  137. }
  138. .group-title {
  139. font-weight: 500;
  140. color: #409eff;
  141. font-size: 15px;
  142. }
  143. </style>