猫妈狗爸伴宠师小程序前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

299 lines
9.2 KiB

  1. <template>
  2. <view class="">
  3. <view class="personal-pet-basic-info">
  4. <view class="personal-pet-info-title border-bottom">
  5. 宠物基本信息
  6. </view>
  7. <u--form labelPosition="left" :model="model" ref="uForm">
  8. <u-form-item required label="昵称" :prop="`petBaseInfo.name`" labelWidth="80" borderBottom>
  9. <u--input v-model="petBaseInfo.name" placeholder="请输入宠物昵称" @change="nameChange"
  10. placeholderStyle="text-align:right;color:#AAA" border="none" inputAlign="right"></u--input>
  11. </u-form-item>
  12. <u-form-item label="性别" :prop="`petBaseInfo.gender`" labelWidth="80" borderBottom
  13. @click="showSex = true">
  14. <u--input v-model="petBaseInfo.gender" disabled disabledColor="#ffffff" placeholder="请选择"
  15. placeholderStyle="text-align:right;color:#AAA" border="none" inputAlign="right"></u--input>
  16. <u-icon slot="right" name="arrow-right" color="#AAA"></u-icon>
  17. </u-form-item>
  18. <u-form-item required label="品种" :prop="`petBaseInfo.breed`" labelWidth="80" borderBottom
  19. @click="breedSelectOpen">
  20. <u--input v-model="petBaseInfo.breed" disabled disabledColor="#ffffff" placeholder="请选择"
  21. placeholderStyle="text-align:right;color:#AAA" border="none" inputAlign="right"></u--input>
  22. <u-icon slot="right" name="arrow-right" color="#AAA"></u-icon>
  23. </u-form-item>
  24. <u-form-item required label="体重" :prop="`petBaseInfo.bodyType`" labelWidth="80" borderBottom
  25. @click="showWeight = true" ref="item1">
  26. <u--input v-model="petBaseInfo.bodyType" disabled disabledColor="#ffffff" placeholder="请选择"
  27. placeholderStyle="text-align:right;color:#AAA" border="none" inputAlign="right"></u--input>
  28. <u-icon slot="right" name="arrow-right" color="#AAA"></u-icon>
  29. </u-form-item>
  30. <u-form-item label="出生年月" :prop="`petBaseInfo.birthDate`" labelWidth="80" borderBottom
  31. @click="yearMonthOpen">
  32. <u--input v-model="petBaseInfo.birthDate" disabled disabledColor="#ffffff" placeholder="请选择"
  33. placeholderStyle="text-align:right;color:#AAA" border="none" inputAlign="right"></u--input>
  34. <u-icon slot="right" name="arrow-right" color="#AAA"></u-icon>
  35. </u-form-item>
  36. <u-form-item required label="性格" :prop="`petBaseInfo.personality`" labelWidth="80" borderBottom
  37. @click="dispositionSelectOpen">
  38. <u--input v-model="petBaseInfo.personality" disabled disabledColor="#ffffff" placeholder="请选择"
  39. placeholderStyle="text-align:right;color:#AAA" border="none" inputAlign="right"></u--input>
  40. <u-icon slot="right" name="arrow-right" color="#AAA"></u-icon>
  41. </u-form-item>
  42. </u--form>
  43. </view>
  44. <view style="background-color: #fffcf2;padding: 10px 20px;" v-show="showDisposition">
  45. <view style="height: 85%;">
  46. <u-checkbox-group v-model="petBaseInfo.personality" @change="checkboxChange" iconPlacement="left"
  47. placement="row" style="flex-wrap: wrap;" activeColor="#ffbf60">
  48. <u-checkbox :customStyle="{margin: '8px'}" v-for="(item, index) in dispositionActions" :key="item"
  49. :label="item" :name="item">
  50. </u-checkbox>
  51. </u-checkbox-group>
  52. </view>
  53. </view>
  54. <u-picker :show="showSex" :showToolbar='false' :columns="sexActions" @cancel="showSex = false"
  55. :immediateChange="true" @change="sexSelect"></u-picker>
  56. <u-picker :show="showWeight" :showToolbar='false' :columns="weightActions" @cancel="showWeight = false"
  57. :immediateChange="true" @change="weightSelect"></u-picker>
  58. <u-overlay :show="showBreed">
  59. <view class="breed-select" style="height: 60%;">
  60. <u-search shape="round" :show-action="false" v-model="searchValue" @change="searchBreed"></u-search>
  61. <view style="padding: 10px;height: 80%;overflow: auto;">
  62. <u-radio-group v-model="tempBreed" placement="column">
  63. <u-radio v-for="(item,index) in searchBreedData" :customStyle="{marginBottom: '8px'}"
  64. activeColor="#ffbf60" :label="item" :name="item" :key="item"></u-radio>
  65. </u-radio-group>
  66. </view>
  67. <view class="personal-pet-breed-btns">
  68. <view class="personal-pet-breed-btn">
  69. <u-button color="#FFF4E4" @click="breedSelectClose">
  70. <view style="color: #FFF4E4;">
  71. 取消
  72. </view>
  73. </u-button>
  74. </view>
  75. <view class="personal-pet-breed-btn" @click="breedSelectConfirm">
  76. <u-button color="#FFBF60">
  77. <view style="color: #fff;">
  78. 确定
  79. </view>
  80. </u-button>
  81. </view>
  82. </view>
  83. </view>
  84. </u-overlay>
  85. <u-datetime-picker :maxDate='getMaxDate()' :minDate="getMinDate()" :show="showBirthday" v-model="tempBirthday"
  86. mode="year-month" @confirm="yearMonthConfirm" @cancel="yearMonthClose"></u-datetime-picker>
  87. </view>
  88. </template>
  89. <script setup>
  90. import {
  91. ref,
  92. onMounted,
  93. watch
  94. } from 'vue';
  95. // 定义 props
  96. const props = defineProps({
  97. petType: {
  98. type: String,
  99. default: 'dog'
  100. },
  101. petBaseInfo: {
  102. type: Object,
  103. default: () => ({
  104. name: '',
  105. gender: '',
  106. breed: '',
  107. bodyType: '',
  108. birthDate: '',
  109. personality: ''
  110. })
  111. }
  112. });
  113. // 定义 emits
  114. const emits = defineEmits(['update:petBaseInfo']);
  115. // 定义响应式数据
  116. const showSex = ref(false);
  117. const showBreed = ref(false);
  118. const showWeight = ref(false);
  119. const showBirthday = ref(false);
  120. const showDisposition = ref(false);
  121. const sexActions = ref([
  122. ['男生', '女生']
  123. ]);
  124. const weightActions = ref([
  125. ['小型(<10 KG)', '中型(10~20KG)', '大型(20KG以上)']
  126. ]);
  127. const dispositionActions = ref([]);
  128. const breedData = ref([]);
  129. const searchBreedData = ref([]);
  130. const tempBreed = ref('');
  131. const searchValue = ref('');
  132. const tempBirthday = ref('');
  133. const tempDisposition = ref('');
  134. const uForm = ref(null);
  135. const item1 = ref(null);
  136. // 定义方法
  137. const nameChange = () => {
  138. updatePetBaseInfo();
  139. };
  140. const sexSelect = (e) => {
  141. props.petBaseInfo.gender = e.value[0];
  142. showSex.value = false;
  143. updatePetBaseInfo();
  144. };
  145. const weightSelect = (e) => {
  146. props.petBaseInfo.bodyType = e.value[0];
  147. showWeight.value = false;
  148. updatePetBaseInfo();
  149. };
  150. const breedSelectOpen = () => {
  151. searchBreedData.value = breedData.value;
  152. searchValue.value = '';
  153. tempBreed.value = props.petBaseInfo.breed;
  154. showBreed.value = true;
  155. };
  156. const searchBreed = () => {
  157. if (searchValue.value && searchValue.value !== '') {
  158. searchBreedData.value = breedData.value.filter(e => e.includes(searchValue.value));
  159. } else {
  160. searchBreedData.value = breedData.value;
  161. }
  162. };
  163. const breedSelectClose = () => {
  164. tempBreed.value = '';
  165. showBreed.value = false;
  166. };
  167. const breedSelectConfirm = () => {
  168. props.petBaseInfo.breed = tempBreed.value;
  169. showBreed.value = false;
  170. updatePetBaseInfo();
  171. };
  172. const yearMonthOpen = () => {
  173. if (props.petBaseInfo.birthDate) {
  174. tempBirthday.value = Number(new Date(props.petBaseInfo.birthDate));
  175. } else {
  176. tempBirthday.value = Number(new Date());
  177. }
  178. showBirthday.value = true;
  179. };
  180. const yearMonthClose = () => {
  181. showBirthday.value = false;
  182. };
  183. const yearMonthConfirm = (e) => {
  184. const timeFormat = uni.$u.timeFormat;
  185. props.petBaseInfo.birthDate = timeFormat(e.value, 'yyyy-mm');
  186. showBirthday.value = false;
  187. updatePetBaseInfo();
  188. };
  189. const dispositionSelectOpen = () => {
  190. tempDisposition.value = props.petBaseInfo.personality;
  191. showDisposition.value = true;
  192. };
  193. const dispositionSelectClose = () => {
  194. tempDisposition.value = '';
  195. showDisposition.value = false;
  196. };
  197. const dispositionSelectConfirm = () => {
  198. props.petBaseInfo.personality = tempDisposition.value;
  199. showDisposition.value = false;
  200. updatePetBaseInfo();
  201. };
  202. const checkboxChange = (n) => {
  203. console.log('change', n);
  204. updatePetBaseInfo();
  205. };
  206. const updatePetBaseInfo = () => {
  207. // 触发 update 事件,将修改后的 petBaseInfo 对象发送给父组件
  208. emits('update:petBaseInfo', props.petBaseInfo);
  209. };
  210. const getPersonalityDataList = () => {
  211. // getDictList('pet_personality').then(res => {
  212. // if (res.code === 200) {
  213. // dispositionActions.value = Array.from(new Set(res.data.map(e => e.dictLabel)));
  214. // } else {
  215. // uni.showToast({
  216. // title: '获取性格失败',
  217. // icon: 'none'
  218. // });
  219. // }
  220. // });
  221. };
  222. const getPetBreed = () => {
  223. let petBreedType = props.petType === 'cat' ? 'pet_brand_cat' : 'pet_brand_dog';
  224. // getDictList(petBreedType).then(res => {
  225. // if (res.code === 200) {
  226. // breedData.value = Array.from(new Set(res.data.map(e => e.dictLabel)));
  227. // } else {
  228. // uni.showToast({
  229. // title: '获取种类失败',
  230. // icon: 'none'
  231. // });
  232. // }
  233. // });
  234. };
  235. const getMaxDate = () => {
  236. return Date.now();
  237. };
  238. const getMinDate = () => {
  239. let dt = new Date();
  240. dt.setFullYear(dt.getFullYear() - 30);
  241. return Date.parse(dt);
  242. };
  243. // 生命周期钩子
  244. onMounted(() => {
  245. // getPersonalityDataList();
  246. // getPetBreed();
  247. });
  248. </script>
  249. <style>
  250. .personal-pet-basic-info {
  251. background-color: #fff;
  252. margin-top: 10px;
  253. padding: 10px 20px;
  254. }
  255. .personal-pet-breed-btns {
  256. display: flex;
  257. justify-content: space-between;
  258. box-sizing: border-box;
  259. background-color: #FFFFFF;
  260. padding: 20rpx 20rpx 40rpx 20rpx;
  261. width: 100%;
  262. height: 160rpx;
  263. position: fixed;
  264. bottom: 0;
  265. z-index: 100;
  266. }
  267. .personal-pet-breed-btn {
  268. width: 40%;
  269. }
  270. </style>