Add.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. <template>
  2. <view>
  3. <up-form labelPosition="left" :model="modelForm" :rules="rulesForm" ref="formRef">
  4. <up-form-item label="姓名" prop="name" borderBottom labelWidth="70">
  5. <up-input v-model="modelForm.name" border="none" placeholder="请输入姓名"></up-input>
  6. </up-form-item>
  7. <up-form-item label="性别" prop="sex" borderBottom @click="() => (sexFlag = true)" labelWidth="70">
  8. <up-input v-model="displaySex" disabled disabledColor="#ffffff" placeholder="请选择性别" border="none"></up-input>
  9. <template #right>
  10. <up-icon name="arrow-right"></up-icon>
  11. </template>
  12. </up-form-item>
  13. <!-- <up-form-item label="关系" prop="label" borderBottom @click="() => (labelFlag = true)" labelWidth="70">
  14. <up-input v-model="modelForm.label" disabled disabledColor="#ffffff" placeholder="请选择关系"
  15. border="none"></up-input>
  16. <template #right>
  17. <up-icon name="arrow-right"></up-icon>
  18. </template>
  19. </up-form-item> -->
  20. <up-form-item label="年龄" prop="age" borderBottom labelWidth="70">
  21. <up-input v-model="modelForm.age" border="none" placeholder="请输入年龄"></up-input>
  22. </up-form-item>
  23. <up-form-item label="手机号" prop="telephone" borderBottom labelWidth="70">
  24. <up-input v-model="modelForm.telephone" border="none" placeholder="请输入手机号"></up-input>
  25. </up-form-item>
  26. <up-form-item label="地区" prop="area" borderBottom @click="onCityWx" labelWidth="70">
  27. <view class="inp"
  28. :class="modelForm.provinceName && modelForm.cityName && modelForm.districtName ? '' : 'address-inp'">
  29. {{ modelForm.provinceName ? modelForm.provinceName : '省' }} /
  30. {{ modelForm.cityName ? modelForm.cityName : '市' }} /
  31. {{ modelForm.districtName ? modelForm.districtName : '区' }}
  32. </view>
  33. <template #right>
  34. <up-icon name="map" size="22" @click="onCityWx"></up-icon>
  35. </template>
  36. </up-form-item>
  37. <up-form-item label="地址" prop="address" borderBottom labelWidth="70" @click="onCityWx">
  38. <up-input v-model="modelForm.address" border="none" placeholder="请输入地址"></up-input>
  39. </up-form-item>
  40. <up-form-item label="门牌号" prop="detailAddress" borderBottom labelWidth="70">
  41. <up-input v-model="modelForm.detailAddress" border="none" placeholder="请输入地址"></up-input>
  42. </up-form-item>
  43. </up-form>
  44. <up-action-sheet :show="sexFlag" :actions="sexOptions" @select="sexSelect"
  45. @close="sexFlag = false"></up-action-sheet>
  46. <up-action-sheet :show="labelFlag" :actions="relaTionsHip" @select="sexSelectsHip"
  47. @close="labelFlag = false"></up-action-sheet>
  48. </view>
  49. </template>
  50. <script setup>
  51. import { ref, reactive, computed } from 'vue'
  52. import pickerAddress from '@/pages_home/components/pickerAddress/pickerAddress.vue' // 地区选择器组件
  53. import { splitAddress } from '@/utils/adress'
  54. import config from '@/config'
  55. const mapKey = config.mapKey // 从配置文件中直接获取腾讯地图key
  56. const formRef = ref(null)
  57. const modelForm = ref({
  58. name: '',
  59. sex: '',
  60. // label: '',
  61. age: '',
  62. telephone: '',
  63. detailAddress: '',
  64. address: '',
  65. provinceName: '', // 省
  66. provinceCode: '',
  67. provinceInd: 0,
  68. cityName: '', // 市
  69. cityCode: '',
  70. cityInd: 0,
  71. districtName: '',
  72. districtCode: '',
  73. districtInd: 0,
  74. })
  75. const rulesForm = ref({
  76. name: [{
  77. type: 'string',
  78. required: true,
  79. message: '请填写姓名',
  80. trigger: ['blur', 'change'],
  81. },
  82. {
  83. // 此为同步验证,可以直接返回true或者false,如果是异步验证,稍微不同,见下方说明
  84. validator: (rule, value, callback) => {
  85. // 调用uview-plus自带的js验证规则,详见:https://uview-plus.jiangruyi.com/js/test.html
  86. return uni.$u.test.chinese(value)
  87. },
  88. message: '姓名必须为中文',
  89. // 触发器可以同时用blur和change,二者之间用英文逗号隔开
  90. trigger: ['change', 'blur'],
  91. },
  92. ],
  93. // sex: {
  94. // type: 'number',
  95. // required: true,
  96. // message: '请选择性别',
  97. // trigger: ['change', 'blur'],
  98. age: [{
  99. type: 'string',
  100. required: true,
  101. message: '请填写年龄',
  102. trigger: ['blur', 'change'],
  103. }
  104. ,
  105. {
  106. validator: (rule, value, callback) => {
  107. return uni.$u.test.digits(value)
  108. },
  109. message: '年龄必须为数字',
  110. // 触发器可以同时用blur和change,二者之间用英文逗号隔开
  111. trigger: ['change', 'blur'],
  112. },
  113. ],
  114. telephone: [{
  115. type: 'string',
  116. required: true,
  117. message: '请填写手机号',
  118. trigger: ['blur', 'change'],
  119. },
  120. {
  121. validator: (rule, value, callback) => {
  122. return uni.$u.test.mobile(value)
  123. },
  124. message: '请输入正确的11位手机号',
  125. trigger: ['change', 'blur'],
  126. }
  127. ],
  128. detailAddress: {
  129. type: 'string',
  130. required: true,
  131. message: '请填写门牌号',
  132. trigger: ['blur', 'change'],
  133. },
  134. address: {
  135. type: 'string',
  136. required: true,
  137. message: '请填写地址',
  138. trigger: ['blur', 'change'],
  139. },
  140. })
  141. let sexFlag = ref(false)
  142. let labelFlag = ref(false)
  143. let addressShow = ref(false)
  144. let index = ref(0)
  145. // 新增一个响应式变量,控制传染病内容的显示
  146. const showContagionContent = ref(false)
  147. const sexOptions = ref([
  148. {
  149. name: '男',
  150. value: 0,
  151. },
  152. {
  153. name: '女',
  154. value: 1,
  155. },
  156. ])
  157. const relaTionsHip = ref([
  158. {
  159. name: '父母',
  160. },
  161. {
  162. name: '子女',
  163. },
  164. {
  165. name: '兄弟',
  166. },
  167. {
  168. name: '朋友',
  169. },
  170. {
  171. name: '同学',
  172. },
  173. {
  174. name: '同事',
  175. },
  176. {
  177. name: '配偶',
  178. },
  179. ])
  180. const displaySex = computed({
  181. get() {
  182. const option = sexOptions.value.find(
  183. (item) => item.value === modelForm.value.sex
  184. )
  185. return option ? option.name : ''
  186. },
  187. set(newValue) {
  188. const option = sexOptions.value.find((item) => item.name === newValue)
  189. if (option) {
  190. modelForm.value.sex = option.value
  191. }
  192. },
  193. })
  194. // 性别选择处理
  195. function sexSelect(e) {
  196. modelForm.value.sex = e.value
  197. sexFlag.value = false
  198. }
  199. function sexSelectsHip(e) {
  200. modelForm.value.label = e.name
  201. labelFlag.value = false
  202. }
  203. function addressChange(info) {
  204. console.log(info, '>>>>data')
  205. const { data, code, index } = info
  206. modelForm.value.provinceName = data[0]
  207. modelForm.value.provinceCode = code[0]
  208. modelForm.value.provinceInd = index[0]
  209. modelForm.value.cityName = data[1]
  210. modelForm.value.cityCode = code[1]
  211. modelForm.value.cityInd = index[1]
  212. modelForm.value.districtName = data[2]
  213. modelForm.value.districtCode = code[2]
  214. modelForm.value.districtInd = index[2]
  215. }
  216. // 使用腾讯地图 API 的函数
  217. function getAdcodeByCoordinates(latitude, longitude) {
  218. if (!mapKey) {
  219. console.error('腾讯地图key为空,请检查配置!');
  220. uni.showToast({
  221. title: '腾讯地图key为空',
  222. icon: 'error'
  223. });
  224. return Promise.reject('地图获取失败');
  225. }
  226. const url = `https://apis.map.qq.com/ws/geocoder/v1/?location=${latitude},${longitude}&key=${mapKey}`;
  227. console.log('请求URL:', url);
  228. return new Promise((resolve, reject) => {
  229. uni.request({
  230. url: url,
  231. success: (res) => {
  232. if (res.data.status === 0) {
  233. const adInfo = res.data.result.ad_info;
  234. resolve({
  235. provinceName: adInfo.province,
  236. cityName: adInfo.city,
  237. districtName: adInfo.district,
  238. provinceCode: adInfo.adcode.slice(0, 2) + '0000', // 提取省编码
  239. cityCode: adInfo.adcode.slice(0, 4) + '00', // 提取市编码
  240. districtCode: adInfo.adcode // 提取区编码
  241. });
  242. } else {
  243. console.error('腾讯地图API错误:', res.data.message);
  244. reject('Error fetching adcode: ' + res.data.message);
  245. }
  246. },
  247. fail: (err) => {
  248. console.error('请求腾讯地图API失败:', err);
  249. reject(err);
  250. }
  251. });
  252. });
  253. }
  254. // 点击地图图标选择地址
  255. // 点击地址图标,选择位置并获取省市区编码
  256. async function onCityWx() {
  257. wx.chooseLocation({
  258. success: async function (res) {
  259. try {
  260. console.log('选择的地址:', res);
  261. // 调用腾讯地图 API 获取省市区编码
  262. const adcodeData = await getAdcodeByCoordinates(res.latitude, res.longitude);
  263. // 更新表单数据
  264. modelForm.value.provinceName = adcodeData.provinceName;
  265. modelForm.value.cityName = adcodeData.cityName;
  266. modelForm.value.districtName = adcodeData.districtName;
  267. modelForm.value.provinceCode = adcodeData.provinceCode;
  268. modelForm.value.cityCode = adcodeData.cityCode;
  269. modelForm.value.districtCode = adcodeData.districtCode;
  270. modelForm.value.address = res.address; // 完整地址
  271. modelForm.value.longitude = res.longitude;
  272. modelForm.value.latitude = res.latitude;
  273. console.log('获取到的省市区信息:', adcodeData);
  274. } catch (err) {
  275. console.error('获取省市区编码失败:', err);
  276. // uni.showToast({
  277. // title: '获取地址编码失败',
  278. // icon: 'error'
  279. // });
  280. }
  281. },
  282. fail: function (err) {
  283. console.error('选择位置失败:', err);
  284. uni.showToast({
  285. title: '获取地址失败',
  286. icon: 'error'
  287. });
  288. }
  289. });
  290. }
  291. defineExpose({
  292. modelForm: modelForm.value,
  293. })
  294. </script>
  295. <style></style>