AcupointEdit.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <script setup lang="ts">
  2. import { ref, computed } from 'vue';
  3. import { notification } from 'ant-design-vue';
  4. import { VxeUI } from 'vxe-pc-ui';
  5. import { MinusCircleOutlined } from '@ant-design/icons-vue';
  6. import { pageAcupointMethod, pageMeridianMethod } from '@/request/api/care.api';
  7. import RemoteSelect from '@/libs/v-select-page/RemoteSelect.vue';
  8. import type { SystemCwModel } from '@/model/care.model';
  9. const props = defineProps<{
  10. data: SystemCwModel;
  11. }>();
  12. const emit = defineEmits(['submit']);
  13. // 定义数据类型接口
  14. interface AcuMeridian {
  15. id: string | number;
  16. name: string;
  17. code: string;
  18. }
  19. // 模式:穴位或经络
  20. const mode = ref('acupoint');
  21. const acupointList = ref<AcuMeridian[]>([]);
  22. const meridianList = ref<AcuMeridian[]>([]);
  23. const showInput = ref(true);
  24. const inputValue = ref('');
  25. // 获取当前模式的API方法
  26. const getApiMethod = computed(() => {
  27. return mode.value === 'acupoint' ? pageAcupointMethod : pageMeridianMethod;
  28. });
  29. // 处理选择事件
  30. function handleSelect(selectedItem: any) {
  31. const list = mode.value === 'acupoint' ? acupointList.value : meridianList.value;
  32. // 判断是否已存在
  33. const exists = list.some((item) => item.name === selectedItem);
  34. if (exists) {
  35. notification.warning({
  36. message: '不能重复添加',
  37. });
  38. inputValue.value = '';
  39. return;
  40. }
  41. if (selectedItem && selectedItem) {
  42. if (mode.value === 'acupoint') {
  43. acupointList.value.push({
  44. name: selectedItem,
  45. id: 0,
  46. code: '',
  47. });
  48. } else {
  49. meridianList.value.push({
  50. name: selectedItem,
  51. id: 0,
  52. code: '',
  53. });
  54. }
  55. inputValue.value = '';
  56. }
  57. }
  58. // 删除项目
  59. function remove(idx: number) {
  60. if (mode.value === 'acupoint') {
  61. acupointList.value.splice(idx, 1);
  62. } else {
  63. meridianList.value.splice(idx, 1);
  64. }
  65. showInput.value = true;
  66. }
  67. // 清空当前模式的数据
  68. function clearAll() {
  69. if (mode.value === 'acupoint') {
  70. acupointList.value = [];
  71. } else {
  72. meridianList.value = [];
  73. }
  74. inputValue.value = '';
  75. }
  76. const tableData = computed(() => {
  77. const list = mode.value === 'acupoint' ? acupointList.value : meridianList.value;
  78. return [...list, { id: '', name: '' }];
  79. });
  80. // 保存
  81. function save() {
  82. props.data.cwcpAcuPoints = [...acupointList.value];
  83. props.data.cwcpAcuMeridians = [...meridianList.value];
  84. props.data.acuMeridianNames = [...meridianList.value].map((item) => item.name);
  85. props.data.acuPointNames = [...acupointList.value].map((item) => item.name);
  86. emit('submit', props.data);
  87. VxeUI.modal.close(`edit-part-modal`);
  88. }
  89. onMounted(() => {
  90. console.log(props.data.cwcpAcuPoints, 'data-onmounted');
  91. if (props.data.cwcpAcuPoints && props.data.cwcpAcuPoints.length > 0 && props.data.cwcpAcuPoints[0].name) {
  92. acupointList.value = [...props.data.cwcpAcuPoints];
  93. }
  94. if (props.data.cwcpAcuMeridians && props.data.cwcpAcuMeridians.length > 0 && props.data.cwcpAcuMeridians[0].name) {
  95. meridianList.value = [...props.data.cwcpAcuMeridians];
  96. }
  97. });
  98. </script>
  99. <template>
  100. <div>
  101. <!-- 模式切换 -->
  102. <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px">
  103. <a-radio-group v-model:value="mode">
  104. <a-radio value="acupoint">穴位</a-radio>
  105. <a-radio value="meridian">经络</a-radio>
  106. </a-radio-group>
  107. </div>
  108. <!-- 表格区域 -->
  109. <!-- 穴位 -->
  110. <div class="mb-2" v-if="mode === 'acupoint'">
  111. <div class="table-header-bar">
  112. <div style="flex: 1"></div>
  113. <a-button type="link" @click="clearAll" class="mb-2" style="float: right; margin-bottom: 4px">清空</a-button>
  114. </div>
  115. <vxe-table :data="tableData" border>
  116. <vxe-column field="id" title="序号" width="60" type="seq" />
  117. <vxe-column field="name" title="穴位/经络/部位">
  118. <template #default="{ rowIndex }">
  119. <template v-if="rowIndex === tableData.length - 1">
  120. <RemoteSelect :load="getApiMethod" key-prop="name" v-model:value="inputValue" style="margin: 0 8px" @update:value="handleSelect" :immediate="true" />
  121. </template>
  122. <template v-else>
  123. {{ tableData[rowIndex].name }}
  124. </template>
  125. </template>
  126. </vxe-column>
  127. <vxe-column title="操作" width="60">
  128. <template #default="{ rowIndex }">
  129. <template v-if="rowIndex !== tableData.length - 1">
  130. <a-button type="text" danger @click="remove(rowIndex)">
  131. <MinusCircleOutlined />
  132. </a-button>
  133. </template>
  134. </template>
  135. </vxe-column>
  136. </vxe-table>
  137. </div>
  138. <!-- 经络 -->
  139. <div class="mb-2" v-if="mode === 'meridian'">
  140. <div class="table-header-bar">
  141. <div style="flex: 1"></div>
  142. <a-button type="link" @click="clearAll" class="mb-2" style="float: right; margin-bottom: 4px">清空</a-button>
  143. </div>
  144. <vxe-table :data="tableData" border>
  145. <vxe-column field="id" title="序号" width="60" type="seq" />
  146. <vxe-column field="name" title="穴位/经络/部位">
  147. <template #default="{ rowIndex }">
  148. <template v-if="rowIndex === tableData.length - 1">
  149. <RemoteSelect :load="getApiMethod" key-prop="name" v-model:value="inputValue" style="margin: 0 8px" @update:value="handleSelect" :immediate="true" />
  150. </template>
  151. <template v-else>
  152. {{ tableData[rowIndex].name }}
  153. </template>
  154. </template>
  155. </vxe-column>
  156. <vxe-column title="操作" width="60">
  157. <template #default="{ rowIndex }">
  158. <template v-if="rowIndex !== tableData.length - 1">
  159. <a-button type="text" danger @click="remove(rowIndex)">
  160. <MinusCircleOutlined />
  161. </a-button>
  162. </template>
  163. </template>
  164. </vxe-column>
  165. </vxe-table>
  166. </div>
  167. <!-- 底部按钮 -->
  168. <div style="margin-top: 40px; text-align: center">
  169. <a-button style="margin-right: 24px" @click="VxeUI.modal.close(`edit-part-modal`)">取消</a-button>
  170. <a-button type="primary" @click="save">保存</a-button>
  171. </div>
  172. </div>
  173. </template>
  174. <style scoped lang="scss">
  175. .table-header-bar {
  176. display: flex;
  177. justify-content: flex-end;
  178. align-items: center;
  179. margin-bottom: 4px;
  180. }
  181. </style>