Browse Source

1,fix phone为空不能显示的bug

2,新增修改用户自己信息(姓名,昵称,手机号)的功能
3,删除一些无用的引用
main
yk 1 year ago
parent
commit
d10f93cfdf
18 changed files with 15586 additions and 24 deletions
  1. +1
    -0
      components.d.ts
  2. +15184
    -1
      package-lock.json
  3. +1
    -0
      package.json
  4. +21
    -4
      project.config.json
  5. +7
    -0
      project.private.config.json
  6. +2
    -1
      src/app.config.ts
  7. +3
    -0
      src/components/my-info-form/index.json
  8. +31
    -0
      src/components/my-info-form/index.scss
  9. +63
    -0
      src/components/my-info-form/index.vue
  10. +1
    -1
      src/pages/contact-edit/index.vue
  11. +4
    -1
      src/pages/contact-pass-records/index.config.ts
  12. +4
    -10
      src/pages/contact/index.vue
  13. +6
    -0
      src/pages/my-info/index.config.ts
  14. +20
    -0
      src/pages/my-info/index.scss
  15. +90
    -0
      src/pages/my-info/index.vue
  16. +10
    -2
      src/pages/settings/index.vue
  17. +1
    -4
      src/pages/web-view/index.vue
  18. +137
    -0
      src/stores/my-info.ts

+ 1
- 0
components.d.ts View File

@@ -12,6 +12,7 @@ declare module 'vue' {
ContactForm: typeof import('./src/components/contact-form/index.vue')['default']
Counter: typeof import('./src/components/Counter.vue')['default']
ExternalLink: typeof import('./src/components/ExternalLink.vue')['default']
MyInfoForm: typeof import('./src/components/my-info-form/index.vue')['default']
Notification: typeof import('./src/components/notification/index.vue')['default']
NutActionSheet: typeof import('@nutui/nutui-taro')['ActionSheet']
NutAvatar: typeof import('@nutui/nutui-taro')['Avatar']


+ 15184
- 1
package-lock.json
File diff suppressed because it is too large
View File


+ 1
- 0
package.json View File

@@ -56,6 +56,7 @@
"dayjs": "^1.11.10",
"graphql": "^16.8.1",
"graphql-tag": "^2.12.6",
"install": "^0.13.0",
"pinia": "^2.1.7",
"taro-icons": "^0.4.0",
"tarojs-router-next": "^3.4.0",


+ 21
- 4
project.config.json View File

@@ -1,5 +1,5 @@
{
"miniprogramRoot": "./dist",
"miniprogramRoot": "dist/",
"projectname": "wxapp-visitor-invite",
"description": "",
"appid": "wx72b4f0e248fc1b2b",
@@ -9,7 +9,24 @@
"enhance": false,
"compileHotReLoad": false,
"postcss": false,
"minified": false
"minified": false,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
}
},
"compileType": "miniprogram"
}
"compileType": "miniprogram",
"libVersion": "3.3.1",
"isGameTourist": false,
"srcMiniprogramRoot": "dist/",
"packOptions": {
"ignore": [],
"include": []
},
"condition": {},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
}
}

+ 7
- 0
project.private.config.json View File

@@ -0,0 +1,7 @@
{
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"projectname": "wxapp-visitor-invite",
"setting": {
"compileHotReLoad": true
}
}

+ 2
- 1
src/app.config.ts View File

@@ -10,7 +10,8 @@ export default defineAppConfig({
'pages/web-view/index',
'pages/contact-pass-records/index',
'pages/contact-edit-logs/index',
'pages/contact-send-invite-sms/index'
'pages/contact-send-invite-sms/index',
'pages/my-info/index'
],
window: {
backgroundTextStyle: 'light',


+ 3
- 0
src/components/my-info-form/index.json View File

@@ -0,0 +1,3 @@
{
"component": true
}

+ 31
- 0
src/components/my-info-form/index.scss View File

@@ -0,0 +1,31 @@
.nut-cell {
background: transparent !important;
}
.nut-cell-group__wrap {
background: transparent !important;
}
.suggestions {
position: absolute;
z-index: 10;
background-color: #FFF;
width: 100vw;
border: solid 1px #DDD;
}
.suggestions > view {
padding: 30px 20px 30px 50px;
border-bottom: solid 1px #DDD;
color: #888;
}

.label {
padding: 30px 20px 10px 50px;
color: #666;
}

.calendar > .nut-cell {
padding: 0;
}

.nut-avatar-cropper::after, .nut-avatar-cropper__edit-text {
background-color: transparent;
}

+ 63
- 0
src/components/my-info-form/index.vue View File

@@ -0,0 +1,63 @@
<script setup lang="ts">
import "./index.scss";
import Taro from "@tarojs/taro";
import {reactive, ref} from 'vue';
import {ScreenHelper, Session} from "../../utils";

import {useStaffItemStore} from "../../stores/my-info";
const me = Session.get("staff")

const staff = useStaffItemStore()

const screenWidth = ScreenHelper.getScreenWidth()

const state = reactive({
newAvatar: undefined
});

const updateFacePhoto = () => {
Taro.chooseImage({
count: 1, // 默认9
sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
success: function (res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
state.newAvatar = res.tempFilePaths
console.log(state.newAvatar)
},
})
}
</script>

<template>

<nut-form>
<nut-form-item>
<view>
<view class="d-flex justify-content-center">
<nut-avatar :size="Math.floor(screenWidth/3)" @click="updateFacePhoto" class="overflow-hidden">
<img v-if="state.newAvatar" :src="state.newAvatar" alt=""/>
<img v-else-if="me.avatar" :src="me.avatar" alt=""/>
<view v-else class="d-flex align-items-center justify-content-center h-100 w-100">
<Text class="fas fa-user fa-5x"></Text>
</view>
</nut-avatar>
</view>
<view class="d-flex justify-content-center pt-3">
<view class="btn-sm btn btn-secondary badge-pill" @tap="updateFacePhoto">{{me.avatar || state.newAvatar ?'更换':'添加'}}面部识别照片</view>
</view>
</view>
</nut-form-item>
<nut-form-item label="姓名">
<nut-input v-model="staff.staff.userName" class="nut-input-text" />
</nut-form-item>
<nut-form-item label="称呼">
<nut-input v-model="staff.staff.nickName" class="nut-input-text">
</nut-input>
</nut-form-item>
<nut-form-item label="电话">
<nut-input v-model="staff.staff.phone" class="nut-input-text" type="number" />
</nut-form-item>

</nut-form>

</template>

+ 1
- 1
src/pages/contact-edit/index.vue View File

@@ -200,7 +200,7 @@ const onSaveAndSendMessage = () => {
</view>

<view class="pl-3 pr-3 pt-2 pb-2">
<nut-button :disabled="contactData.phone.length !== 11 || contactData.isBlock" block type="info" @tap="onSaveAndSendMessage">保存并发送邀约短信</nut-button>
<nut-button :disabled="!(contactData.phone) || contactData.phone.length !== 11 || contactData.isBlock" block type="info" @tap="onSaveAndSendMessage">保存并发送邀约短信</nut-button>
</view>

<view class="pl-3 pr-3 pt-2 pb-2">


+ 4
- 1
src/pages/contact-pass-records/index.config.ts View File

@@ -2,5 +2,8 @@ export default definePageConfig({
navigationBarTitleText: '',
usingComponents: {},
navigationStyle: 'custom',
disableScroll: true
disableScroll: true,
enablePullDownRefresh: true,//开启页面下拉刷新
backgroundTextStyle: 'dark'//设置下拉刷新的三个点,默认白色

})

+ 4
- 10
src/pages/contact/index.vue View File

@@ -1,16 +1,10 @@
<script lang="ts" setup>
import Contact from "../../components/contact"
import { Router } from 'tarojs-router-next'
import {reactive, ref} from 'vue';
import {registerRouterBackListener, Router} from 'tarojs-router-next'
import {reactive} from 'vue';
import './index.scss'
import { useContactsStore, ContactData } from '../../stores/contacts'
import { registerRouterBackListener } from 'tarojs-router-next'



import {gql} from "graphql-tag";
import {PinyinHelper, GQLRequest, weappAuth} from "../../utils";
import {useAuthStore} from "../../stores/auth";
import {ContactData, useContactsStore} from '../../stores/contacts'
import {weappAuth} from "../../utils";

// defineExpose({
// loadContactsFromServer,


+ 6
- 0
src/pages/my-info/index.config.ts View File

@@ -0,0 +1,6 @@
export default definePageConfig({
navigationBarTitleText: '',
usingComponents: {},
navigationStyle: 'custom',
disableScroll: true
})

+ 20
- 0
src/pages/my-info/index.scss View File

@@ -0,0 +1,20 @@
page {
height: 100%;
}

.nut-navbar {
background: transparent;
}

.scroll {
flex: 1;
overflow: scroll;
}

.save-button {
font-size: 36px
}

.nut-action-sheet__item {
color: red !important;
}

+ 90
- 0
src/pages/my-info/index.vue View File

@@ -0,0 +1,90 @@
<script setup lang="ts">
import {Router} from 'tarojs-router-next'
import './index.scss'
import Taro from "@tarojs/taro";
import {Session} from "../../utils";
import {useStaffItemStore} from "../../stores/my-info";

const staffData = Router.getData()
const staff = useStaffItemStore()

const myData = Session.get("staff")
console.log(myData);
staff.setStaff(myData)

const goBack = () => {
Router.back()
}
const onSaveClicked = () => {
console.log(staffData);
if (myData.name === ""){
Taro.showToast({
title: '名字不能为空',
icon: 'none',
duration: 2000})
return
}

Taro.showLoading({
title: 'loading',
})

console.log("onSaveClicked")
console.log(staff.staff)

staff.updateStaff().then(r => {
console.log("updateStaff", r)
}).catch(error => {
Taro.hideLoading()
if (error) {
const errorMessage = (typeof error === "string")? error : "服务器错误,请稍后重试"
Taro.showToast({
title: errorMessage,
icon: 'none',
duration: 2000
})
}
else {
Taro.showToast({
title: '网络异常,请稍后重试',
icon: 'none',
duration: 2000
})
}

console.log("error", error)
})
}



</script>

<template>


<view class="h-100 d-flex flex-column">
<BackgroundBasic/>
<NutNavbar title=""></NutNavbar>
<view class="p-3 d-flex">
<view class="flex-grow-1">
<view class="h3">
<view class="fas fa-chevron-left text-primary" @tap="goBack()" hover-class="btn-hover-primary"/>
更新个人信息
</view>
<view class="text-black-50"></view>
</view>
<view class="d-flex align-items-end pt-3">
<view class="text-primary save-button pt-3" hover-class="btn-hover-primary" @tap="onSaveClicked()">保存</view>
</view>
</view>


<view class="scroll">
<MyInfoForm :data="staffData"/>
</view>


</view>

</template>

+ 10
- 2
src/pages/settings/index.vue View File

@@ -35,6 +35,10 @@ function init() {
})
}

const onAvatarClick = () => {
Router.toMyInfo(Session.get("staff"))
}

const onAuthErrorRefresh = () => {
init()
}
@@ -71,6 +75,10 @@ const onAboutUsClicked = () => {

}

const goToMyInfoEditPage = (item) => {
Router.toMyInfoEdit({ data: item })
}

</script>

<template>
@@ -104,8 +112,8 @@ const onAboutUsClicked = () => {
</view>
<View v-else class="w-100" style="overflow-x: hidden">
<View class="d-flex justify-content-center pt-5 pb-3">
<NutAvatar size="large" class="overflow-hidden">
<img :src="Session.get('staff').avatar" />
<NutAvatar size="large" class="overflow-hidden" @click="onAvatarClick">
<img :src="Session.get('staff').avatar" alt=""/>
</NutAvatar>
</View>
<View class="text-center h4">


+ 1
- 4
src/pages/web-view/index.vue View File

@@ -1,9 +1,6 @@
<script setup>
import {Component} from 'react'
import Taro,{ Current } from '@tarojs/taro'
import './index.scss'
import {Session} from "../../utils";
import {Router, NavigateType} from "tarojs-router-next";
import {Router} from "tarojs-router-next";
import {View} from "@tarojs/components";

const params = Router.getParams()


+ 137
- 0
src/stores/my-info.ts View File

@@ -0,0 +1,137 @@
// https://pinia.esm.dev/introduction.html
import {defineStore} from 'pinia'
import {GQLRequest, Session} from "../utils";
import {gql} from "graphql-tag";
import {ref, Ref, UnwrapRef} from "vue";
import Taro from "@tarojs/taro";


export const useStaffItemStore = defineStore('my-info', () => {

interface Staff {
id?: number
userName: string
userType: number
nickName: string
avatar: string
phone: string
sex: string
deptId: string
resourceId: number
delFlag: number
}

const staff: Ref<UnwrapRef<Staff>> = ref(getEmptyStaffData())
const staffNewAvatar: Ref<UnwrapRef<string>> = ref("")

function setStaff(staffItem: Staff) {
staff.value = staffItem
console.log("setContact", staff.value)
}
function setNewAvatar(avatar: string) {
staffNewAvatar.value = avatar
}

function getEmptyStaffData(): Staff {
return {
id: undefined,
userName: "",
userType: undefined,
nickName: "",
avatar: "",
phone: "",
sex: "",
deptId: "",
resourceId: undefined,
delFlag: 0
}
}

const UPDATE_STAFF = gql`
mutation UpdateStaff($staffId: ID!, $id: ID!, $userName: String!, $nickName: String, $phone: String, $resourceId: ID ) {
updateStaff( staffId: $staffId, input: {
id: $id,
userName: $userName,
nickname: $nickName,
phone: $phone,
resourceId: $resourceId
} ) {
id
}
}
`

const DELETE_VISITOR = gql`
mutation DeleteStaff($id: ID! ) {
deleteStaff( id: $id )
}
`


function updateStaff() {

const id = staff.value.id
const userName = staff.value.userName
const nickName = staff.value.nickName
const phone = staff.value.phone


return new Promise((resolve, reject) => {
if (staffNewAvatar.value !== "") {
uploadFace().then(r => {
console.log(r)
const resourceId = r.data.resourceId
GQLRequest.query(UPDATE_STAFF, { id, userName, nickName, phone, resourceId })
.then(r=> {
// contact.value.id = r.data.updateStaff.id
resolve(r)
})
.catch(e=> reject(e))
}).catch(e => {
reject(e.msg)
})
}
else {
GQLRequest.query(UPDATE_STAFF, {id, userName, nickName, phone })
.then(r=> {
// contact.value.id = r.data.updateStaff.id
resolve(r)
})
.catch(e=> reject(e))
}
})
}


function deleteStaff() {
const id = staff.value.id
const staffId = Session.get("staff").id

return GQLRequest.query(DELETE_VISITOR, { staffId, id })
}

function uploadFace() {
return new Promise((resolve, reject) => {
console.log("aaaaaaaa", staffNewAvatar.value)
Taro.uploadFile({
url: SERVER_URL + '/system/resources/upload-face',
header: {
Authorization: 'Bearer ' + Session.get('access_token'),
},
name: "file",
filePath: staffNewAvatar.value,
success: result => {
const data = JSON.parse(result.data)
if (result.statusCode == 200 && data.code !== 500) resolve(data)
else reject(data)
},
fail: res => {
reject(res)
}
})
})
}


return { staff, setStaff, updateStaff, deleteStaff, getEmptyStaffData, setNewAvatar }
})

Loading…
Cancel
Save