index.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <script setup lang="tsx">
  2. import { ref } from 'vue';
  3. import { NDynamicInput, NInputNumber, NSelect } from 'naive-ui';
  4. import { fetchGetAllChannelList } from '@/service/api/goods/store-goods';
  5. import { fetchChannelList, fetchGetAddOrEditTransport, fetchGetTransport } from '@/service/api/common';
  6. import { useTabStore } from '@/store/modules/tab';
  7. import { useForm } from '@/components/zt/Form/hooks/useForm';
  8. const isSubmit = ref(false);
  9. const tabStore = useTabStore();
  10. interface Options {
  11. value: any;
  12. index: number;
  13. }
  14. const ChannelOptions = ref<Api.goods.Channel[]>([]);
  15. const [registerForm, { getFieldsValue, validate, setFieldsValue }] = useForm({
  16. schemas: [
  17. {
  18. field: 'id',
  19. component: 'NInput',
  20. label: 'false',
  21. show: false
  22. },
  23. {
  24. field: 'name',
  25. component: 'NDynamicInput',
  26. label: '配送费/运费',
  27. render({ model, field }) {
  28. return (
  29. <div class={'flex flex-wrap items-center'}>
  30. <div class={'h38px flex items-center'}>
  31. <div class={'w-200px text-center'}> 企业 </div>
  32. <div class={'ml-3 w-200px text-center'}> 费用(元) </div>
  33. <div class={'ml-3 w-200px text-center'}> 重量(kg) </div>
  34. <div class={'ml-3 w-200px text-center'}> 分单(km) </div>
  35. </div>
  36. <NDynamicInput
  37. value={model[field]}
  38. onUpdate:value={value => (model[field] = value)}
  39. v-slots={(row: Options) => handleCreatInput(model, field, row)}
  40. onCreate={() => handleAdd()}
  41. max={ChannelOptions.value.length}
  42. ></NDynamicInput>
  43. </div>
  44. );
  45. },
  46. required: true,
  47. defaultValue: []
  48. }
  49. ],
  50. labelWidth: 120,
  51. layout: 'horizontal',
  52. collapsedRows: 1,
  53. showActionButtonGroup: false,
  54. gridProps: {
  55. cols: '1',
  56. itemResponsive: true
  57. }
  58. });
  59. function handleCreatInput(model: any, field: any, row: Options) {
  60. return (
  61. <div class={'flex items-center'}>
  62. <div class={'w-200px'}>
  63. <NSelect
  64. value={model[field][row.index].channelId}
  65. labelField="channelName"
  66. valueField="id"
  67. options={ChannelOptions.value}
  68. onUpdate:value={vlaue => {
  69. ChannelOptions.value.map(it => {
  70. if (it.id == model[field][row.index].channelId) {
  71. it.disabled = false;
  72. }
  73. return it;
  74. });
  75. model[field][row.index].channelId = vlaue ? Number(vlaue) : undefined;
  76. handleGetChannelId(vlaue, row.index);
  77. }}
  78. onUpdate:show={value => {
  79. ChannelOptions.value.map(it => {
  80. if (it.id == model[field][row.index].channelId) {
  81. if (value) {
  82. it.disabled = false;
  83. }
  84. if (!value) {
  85. it.disabled = true;
  86. }
  87. }
  88. return it;
  89. });
  90. }}
  91. ></NSelect>
  92. </div>
  93. <div class={'ml-3 w-200px'}>
  94. <NInputNumber
  95. value={model[field][row.index].freightFee}
  96. min={1}
  97. onUpdate:value={value => {
  98. model[field][row.index].freightFee = value;
  99. }}
  100. ></NInputNumber>
  101. </div>
  102. <div class={'ml-3 w-200px'}>
  103. <NInputNumber
  104. value={model[field][row.index].weight}
  105. min={1}
  106. onUpdate:value={value => {
  107. model[field][row.index].weight = value;
  108. }}
  109. v-slots={{ prefix: () => '每', suffix: () => 'Kg' }}
  110. ></NInputNumber>
  111. </div>
  112. <div class={'ml-3 w-200px'}>
  113. <NInputNumber
  114. placeholder={'请输入配送距离'}
  115. value={model[field][row.index].distance}
  116. onUpdate:value={val => (model[field][row.index].distance = val)}
  117. v-slots={{ prefix: () => '大于', suffix: () => 'km' }}
  118. ></NInputNumber>
  119. </div>
  120. </div>
  121. );
  122. }
  123. function close() {
  124. tabStore.removeTab(tabStore.activeTabId);
  125. }
  126. async function getChannelList() {
  127. const { data } = await fetchGetAllChannelList();
  128. if (!data) return;
  129. ChannelOptions.value = data;
  130. }
  131. getChannelList();
  132. async function getData() {
  133. const { data } = await fetchChannelList();
  134. if (data) {
  135. setFieldsValue({ name: data.records });
  136. }
  137. }
  138. getData();
  139. function handleAdd() {
  140. return {
  141. channelId: null,
  142. freightFee: 1,
  143. distance: null,
  144. weight: 10
  145. };
  146. }
  147. async function save() {
  148. await validate();
  149. isSubmit.value = true;
  150. const form = getFieldsValue();
  151. await fetchGetAddOrEditTransport(form);
  152. isSubmit.value = false;
  153. getData();
  154. }
  155. async function handleGetChannelId(channelId: number, idx: number) {
  156. const res = await fetchGetTransport(channelId);
  157. const form = getFieldsValue();
  158. const newName = JSON.parse(JSON.stringify(form.name));
  159. newName[idx].distance = res.data?.distance;
  160. newName[idx].freightFee = res.data?.freightFee;
  161. newName[idx].weight = res.data?.weight;
  162. setFieldsValue({ name: newName });
  163. }
  164. </script>
  165. <template>
  166. <LayoutTable>
  167. <NCard title="配送费&运费配置" :bordered="false" size="small" segmented class="card-wrapper">
  168. <NScrollbar x-scrollable>
  169. <BasicForm @register-form="registerForm"></BasicForm>
  170. </NScrollbar>
  171. <template #footer>
  172. <NSpace justify="end">
  173. <NButton size="small" @click="close">关闭</NButton>
  174. <NButton type="primary" size="small" :loading="isSubmit" @click="save">保存</NButton>
  175. </NSpace>
  176. </template>
  177. </NCard>
  178. </LayoutTable>
  179. </template>
  180. <style scoped></style>