animals-input.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <template>
  2. <view class="flex1">
  3. <view>
  4. <up-swipe-action>
  5. <template v-for="(item, index) in list" :key="index">
  6. <up-swipe-action-item class="mb-20" :options="options" @click="clickPlotSwipe($event, item, index)">
  7. <view class="ul-block-item pd-24">
  8. {{ item.animalId }}
  9. </view>
  10. </up-swipe-action-item>
  11. </template>
  12. </up-swipe-action>
  13. </view>
  14. <view class="d-flex">
  15. <up-button class="flex1 mr-20" color="#18BECA" plain @click="onScan">
  16. <image class="w-36 h-36 mr-10" src="https://yujin-szyy.oss-cn-chengdu.aliyuncs.com/szyy/images-plt/common/scan_icon_o.png" mode="widthFix" />
  17. <span>扫一扫添加</span>
  18. </up-button>
  19. <up-button @click="onAddClick" class="flex1" color="#37A954" plain>
  20. <image class="w-36 h-36 mr-10" src="https://yujin-szyy.oss-cn-chengdu.aliyuncs.com/szyy/images-plt/common/edit_icon.png" mode="widthFix" />
  21. <span>手动输入添加</span>
  22. </up-button>
  23. </view>
  24. </view>
  25. <ut-confirm-dialog title="添加个体标识" v-model:show="showPop" width="680rpx">
  26. <view>
  27. <up-form ref="upFormRef" :model="form" :rules="rules" labelWidth="auto" class="p-rtv" labelPosition="top">
  28. <up-form-item label="个体标识号" border-bottom prop="animalId" required>
  29. <up-input v-model="form.animalId" border="none" :maxlength="200" clearable placeholder="请输入个体标识号"></up-input>
  30. </up-form-item>
  31. </up-form>
  32. </view>
  33. <template #footer>
  34. <view class="d-flex j-c pd-30">
  35. <up-button @click="showPop = false" class="mr-30" style="color: #333" color="#F2F2F2">取消</up-button>
  36. <up-button @click="onConfirm" type="primary">确认</up-button>
  37. </view>
  38. </template>
  39. </ut-confirm-dialog>
  40. </template>
  41. <script setup lang="ts">
  42. const props = defineProps({
  43. modelValue: {
  44. type: Array,
  45. default: () => [],
  46. },
  47. });
  48. const upFormRef = ref();
  49. const rules = reactive({
  50. animalId: [{ required: true, message: '请输入个体标识号', trigger: 'blur' }],
  51. });
  52. const showPop = ref(false);
  53. const form = ref({
  54. animalId: '',
  55. });
  56. // -1 表示新增,其它为编辑的下标
  57. const editIndex = ref<number>(-1);
  58. const emit = defineEmits(['update:modelValue']);
  59. const list = ref<any[]>(props.modelValue);
  60. const options = ref([
  61. {
  62. text: '编辑',
  63. name: 'edit',
  64. style: {
  65. backgroundColor: '#37a954',
  66. color: '#fff',
  67. },
  68. },
  69. {
  70. text: '删除',
  71. name: 'delete',
  72. style: {
  73. backgroundColor: '#FF3B30',
  74. color: '#fff',
  75. },
  76. },
  77. ]);
  78. const clickPlotSwipe = (e: any, item: any, index: number) => {
  79. console.log(e);
  80. if (e.index == 0) {
  81. // 编辑个体标识
  82. console.log('编辑个体标识', item, index);
  83. editIndex.value = index;
  84. form.value.animalId = item?.animalId || '';
  85. showPop.value = true;
  86. } else if (e.index == 1) {
  87. // 删除个体标识
  88. list.value.splice(index, 1);
  89. emit('update:modelValue', [...list.value]);
  90. }
  91. };
  92. const onConfirm = async () => {
  93. try {
  94. // uview-plus 的 up-form 暴露 validate 方法
  95. await upFormRef.value?.validate();
  96. if (editIndex.value > -1) {
  97. // 编辑模式:更新当前项
  98. list.value[editIndex.value] = { ...list.value[editIndex.value], ...form.value };
  99. } else {
  100. // 新增模式:追加一项
  101. list.value.push({ ...form.value });
  102. }
  103. emit('update:modelValue', [...list.value]);
  104. showPop.value = false;
  105. form.value.animalId = '';
  106. editIndex.value = -1;
  107. } catch (e) {
  108. // 校验不通过
  109. }
  110. };
  111. // 手动新增按钮点击
  112. const onAddClick = () => {
  113. editIndex.value = -1;
  114. form.value.animalId = '';
  115. showPop.value = true;
  116. };
  117. // 扫一扫添加
  118. const onScan = () => {
  119. // #ifdef MP-WEIXIN
  120. uni.scanCode({
  121. onlyFromCamera: true,
  122. success: (res) => {
  123. const code = (res.result || '').trim();
  124. if (!code) return;
  125. // 直接追加到列表
  126. list.value.push({ animalId: code });
  127. emit('update:modelValue', [...list.value]);
  128. },
  129. fail: () => {},
  130. });
  131. // #endif
  132. // 其他端如 H5/App 可按需再做兼容
  133. };
  134. watch(
  135. () => props.modelValue,
  136. (newVal) => {
  137. list.value = newVal;
  138. },
  139. );
  140. </script>
  141. <script lang="ts">
  142. export default {
  143. options: {
  144. // 微信小程序中 options 选项
  145. multipleSlots: true, // 在组件定义时的选项中启动多slot支持,默认启用
  146. styleIsolation: 'shared', // 启动样式隔离。当使用页面自定义组件,希望父组件影响子组件样式时可能需要配置。具体配置选项参见:微信小程序自定义组件的样式
  147. addGlobalClass: true, // 表示页面样式将影响到自定义组件,但自定义组件中指定的样式不会影响页面。这个选项等价于设置 styleIsolation: apply-shared
  148. virtualHost: true, // 将自定义节点设置成虚拟的,更加接近Vue组件的表现。我们不希望自定义组件的这个节点本身可以设置样式、响应 flex 布局等,而是希望自定义组件内部的第一层节点能够响应 flex 布局或者样式由自定义组件本身完全决定
  149. },
  150. };
  151. </script>
  152. <style lang="scss" scoped>
  153. .ul-block-item {
  154. border-radius: 16rpx;
  155. border: 1px solid #AFDDBB;
  156. // 字体数字可换行
  157. word-break: break-all;
  158. }
  159. </style>