index.vue 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. <template>
  2. <view class="content">
  3. <view class="one">
  4. <form @submit="formSubmit">
  5. <view class="value other" style="display: none;">
  6. <view class="title">id</view>
  7. <view class="label">
  8. <input name="id" class="input" :value="form.id" placeholder="请输入id" />
  9. </view>
  10. </view>
  11. <view class="value icon">
  12. <view class="title">头像</view>
  13. <view class="label">
  14. <image class="image" mode="aspectFill" :src="form.icon||config.logoUrl" @tap="Preview"></image>
  15. </view>
  16. </view>
  17. <view class="remark">
  18. 实名信息(仅用于赛事报名、参赛证功能)
  19. </view>
  20. <view class="value other">
  21. <view class="title">姓名</view>
  22. <view class="label">
  23. <input name="name" class="input" :value="form.name" placeholder="请输入真实姓名" />
  24. </view>
  25. </view>
  26. <view class="value other margin">
  27. <view class="title">昵称</view>
  28. <view class="label">
  29. <input name="nickname" class="input" :value="form.nickname" placeholder="请输入昵称" />
  30. </view>
  31. </view>
  32. <view class="value other">
  33. <view class="title">性别</view>
  34. <view class="label">
  35. <picker name="sex" @change="sexChange" :value="index" :range="sexList" range-key="dictLabel">
  36. <view class="picker">{{form.sex||'请选择性别'}}</view>
  37. </picker>
  38. </view>
  39. </view>
  40. <view class="value other">
  41. <view class="title">手机号</view>
  42. <view class="label">
  43. <input name="phone" class="input" :value="form.phone" placeholder="请输入手机号" />
  44. </view>
  45. </view>
  46. <view class="value other">
  47. <view class="title">城市</view>
  48. <view class="label" @tap="toCity">
  49. <text v-if="form.city">{{form.city}}</text>
  50. <text v-else>请选择城市</text>
  51. </view>
  52. </view>
  53. <view class="value other" style="display: none;">
  54. <view class="title">城市</view>
  55. <view class="label">
  56. <input name="city" class="input" :value="form.city" placeholder="请输入城市" />
  57. </view>
  58. </view>
  59. <view class="value other">
  60. <view class="title">身高</view>
  61. <view class="label">
  62. <input name="height" class="input" :value="form.height" placeholder="请输入身高(cm)" />
  63. </view>
  64. </view>
  65. <view class="value other">
  66. <view class="title">体重</view>
  67. <view class="label">
  68. <input name="weight" class="input" :value="form.weight" placeholder="请输入体重(kg)" />
  69. </view>
  70. </view>
  71. <view class="value other margin">
  72. <view class="title">主要项目</view>
  73. <view class="label">
  74. <picker name="type" @change="typeChange" :value="index" :range="typeList" range-key="dictLabel">
  75. <view class="picker">{{form.type||'请选择主要项目'}}</view>
  76. </picker>
  77. </view>
  78. </view>
  79. <view class="value other">
  80. <view class="title">球龄</view>
  81. <view class="label">
  82. <picker name="ballYears" @change="ballYearsChange" :value="index" :range="ballYearsList"
  83. range-key="dictLabel">
  84. <view class="picker">{{form.ballYears||'请选择球龄'}}</view>
  85. </picker>
  86. </view>
  87. </view>
  88. <view class="value other">
  89. <view class="title">队内位置</view>
  90. <view class="label">
  91. <picker name="place" @change="placeChange" :value="index" :range="placeList"
  92. range-key="dictLabel">
  93. <view class="picker">{{form.place||'请选择队内位置'}}</view>
  94. </picker>
  95. </view>
  96. </view>
  97. <view class="button">
  98. <button type="warn" size="mini" form-type="submit">保存</button>
  99. </view>
  100. </form>
  101. </view>
  102. </view>
  103. </template>
  104. <script setup lang="ts">
  105. import { getCurrentInstance, computed, ref } from 'vue';
  106. //该依赖已内置不需要单独安装
  107. import { onLoad } from "@dcloudio/uni-app";
  108. // 请求接口
  109. const $api = getCurrentInstance()?.appContext.config.globalProperties.$api;
  110. const $config = getCurrentInstance()?.appContext.config.globalProperties.$config;
  111. const $apifile = getCurrentInstance()?.appContext.config.globalProperties.$apifile;
  112. // openid
  113. const openid = computed(() => {
  114. return uni.getStorageSync('openid');
  115. })
  116. // 基本信息
  117. const config = ref({ logoUrl: '' });
  118. // 用户信息
  119. const form = ref({ icon: '' });
  120. // 字典表
  121. const sexList = ref([]);
  122. const typeList = ref([]);
  123. const placeList = ref([]);
  124. const ballYearsList = ref([]);
  125. onLoad(async () => {
  126. await searchOther();
  127. await searchConfig();
  128. await search();
  129. uni.$on('setCity', function (city) {
  130. form.value.city = city
  131. })
  132. })
  133. // 查询其他信息
  134. const searchOther = async () => {
  135. let res;
  136. // 性别
  137. res = await $api(`dict/data/list`, 'GET', { dictType: 'sys_user_sex', status: '0' });
  138. if (res.code === 200 && res.total > 0) sexList.value = res.rows
  139. // 主要项目
  140. res = await $api(`dict/data/list`, 'GET', { dictType: 'sys_user_type', status: '0' });
  141. if (res.code === 200 && res.total > 0) typeList.value = res.rows
  142. // 队内位置
  143. res = await $api(`dict/data/list`, 'GET', { dictType: 'sys_user_place', status: '0' });
  144. if (res.code === 200 && res.total > 0) placeList.value = res.rows
  145. // 球龄
  146. res = await $api(`dict/data/list`, 'GET', { dictType: 'sys_user_year', status: '0' });
  147. if (res.code === 200 && res.total > 0) ballYearsList.value = res.rows
  148. };
  149. // config信息
  150. const searchConfig = async () => {
  151. config.value = uni.getStorageSync('config');
  152. };
  153. // 查询
  154. const search = async () => {
  155. const res = await $api(`matchUser/find`, 'GET', {
  156. openid: openid.value
  157. });
  158. if (res.code === 200) {
  159. if (res.data) {
  160. form.value = res.data
  161. form.value.sex = toData(form.value.sex, sexList.value)
  162. form.value.type = toData(form.value.type, typeList.value)
  163. form.value.place = toData(form.value.place, placeList.value)
  164. form.value.ballYears = toData(form.value.ballYears, ballYearsList.value)
  165. }
  166. else {
  167. uni.navigateTo({
  168. url: `/pages/login/index`,
  169. })
  170. }
  171. } else {
  172. uni.showToast({
  173. title: res.msg || '',
  174. icon: 'error',
  175. });
  176. }
  177. };
  178. // 处理字典表数据
  179. const toData = (value, list) => {
  180. if (value) return value = list[value].dictLabel
  181. };
  182. // 城市选择
  183. const toCity = () => {
  184. if (form.value.city) {
  185. uni.navigateTo({
  186. url: `/pagesHome/city/index?city=${form.value.city}`,
  187. })
  188. } else {
  189. uni.navigateTo({
  190. url: `/pagesHome/city/index`,
  191. })
  192. }
  193. };
  194. // 性别选择
  195. const sexChange = (e) => {
  196. const data = sexList.value[e.detail.value]
  197. if (data) form.value.sex = data.dictLabel
  198. };
  199. // 主要项目选择
  200. const typeChange = (e) => {
  201. const data = typeList.value[e.detail.value]
  202. if (data) form.value.type = data.dictLabel
  203. };
  204. // 队内位置别选择
  205. const placeChange = (e) => {
  206. const data = placeList.value[e.detail.value]
  207. if (data) form.value.place = data.dictLabel
  208. };
  209. // 球龄选择
  210. const ballYearsChange = (e) => {
  211. const data = ballYearsList.value[e.detail.value]
  212. if (data) form.value.ballYears = data.dictLabel
  213. };
  214. // 上传图片
  215. const Preview = () => {
  216. uni.chooseImage({
  217. count: 1,
  218. sizeType: ['original', 'compressed'],
  219. sourceType: ['album', 'camera'],
  220. success: async function (res) {
  221. let tempFile = JSON.parse(JSON.stringify(res.tempFilePaths));
  222. const arr = await $apifile(`/common/upload`, 'file', tempFile[0],
  223. 'file');
  224. if (arr.code == 200) {
  225. form.value.icon = arr.url
  226. } else {
  227. uni.showToast({
  228. title: arr.msg,
  229. icon: 'none'
  230. });
  231. }
  232. }
  233. });
  234. };
  235. // 保存
  236. const formSubmit = async (e) => {
  237. let data = e.detail.value;
  238. data.icon = form.value.icon;
  239. data = delEmptyQueryNodes(data);
  240. const arr = await $api(`matchUser`, 'PUT', data);
  241. if (arr.code === 200) {
  242. search();
  243. } else {
  244. uni.showToast({
  245. title: arr.msg,
  246. icon: 'error'
  247. });
  248. }
  249. };
  250. // 去除obj里为null的数据
  251. const delEmptyQueryNodes = (obj = {}) => {
  252. Object.keys(obj).forEach((key) => {
  253. let value = obj[key];
  254. value && typeof value === 'object' && delEmptyQueryNodes(value);
  255. (value === '' || value === null || value === undefined || value.length === 0 || Object.keys(value).length === 0) && delete obj[key];
  256. });
  257. return obj;
  258. };
  259. </script>
  260. <style lang="scss" scoped>
  261. .content {
  262. display: flex;
  263. flex-direction: column;
  264. width: 100vw;
  265. height: 100vh;
  266. background-color: var(--footColor);
  267. .one {
  268. .icon {
  269. padding: 2vw;
  270. }
  271. .margin {
  272. margin: 3vw 0 0 0;
  273. }
  274. .other {
  275. padding: 3vw 2vw;
  276. border-bottom: 1px solid var(--footColor);
  277. }
  278. .value {
  279. display: flex;
  280. justify-content: space-between;
  281. align-items: center;
  282. background-color: var(--mainColor);
  283. .label {
  284. .input {
  285. text-align: right;
  286. }
  287. .image {
  288. width: 15vw;
  289. height: 15vw;
  290. border-radius: 20vw;
  291. }
  292. }
  293. }
  294. .remark {
  295. padding: 4vw 2vw;
  296. text-align: center;
  297. color: var(--f99Color);
  298. font-size: var(--font18Size);
  299. }
  300. .button {
  301. margin: 2vw 0 0 0;
  302. text-align: center;
  303. button {
  304. font-size: var(--font14Size);
  305. border-radius: 2vw;
  306. }
  307. }
  308. }
  309. }
  310. </style>