Add.vue 8.8 KB

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