hookehuyr

✨ feat(新增儿童模块): 联调图片上传接口

1 +import { v4 as uuidv4 } from 'uuid';
2 +import { ref, reactive } from 'vue'
3 +import axios from '@/utils/axios';
4 +import { Toast } from 'vant';
5 +import qs from 'Qs'
6 +
7 +// tslint:disable
8 +export const useUpload = () => {
9 + let lock_btn = ref(false); // 保存按钮锁
10 + let fileList = ref([]);
11 + let metaId = ref('');
12 + let upload_image = reactive({ meta_id: '' });
13 + const afterRead = (res) => {
14 + lock_btn.value = true; // 上传开始, 不能保存
15 + let affix = uuidv4();
16 + // 此时可以自行将文件上传至服务器
17 + let dataURL = res.content;
18 + let base64url = dataURL.slice(dataURL.indexOf(',') + 1); // 截取前缀的base64 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAnoAAAJeCAYAA.......
19 + // 获取七牛token
20 + axios.post('/srv/?a=upload', qs.stringify({
21 + filename: `${affix}_${res.file.name}`,
22 + file: base64url
23 + }))
24 + .then(res => {
25 + if (res.data.code === 1) {
26 + let config = {
27 + headers: {
28 + 'Content-Type': 'application/octet-stream',
29 + 'Authorization': 'UpToken ' + res.data.token, // UpToken后必须有一个 ' '(空格)
30 + }
31 + }
32 + // 上传七牛服务器
33 + axios.post('http://upload.qiniup.com/putb64/-1/key/' + res.data.key, base64url, config)
34 + .then(res => {
35 + if (res.data.filekey) {
36 + let info = res.data;
37 + // 保存图片返回ID
38 + axios.post('/srv/?a=upload&t=save_file', qs.stringify({
39 + format: info.image_info.format,
40 + hash: info.hash,
41 + height: info.image_info.height,
42 + width: info.image_info.width,
43 + filekey: info.filekey,
44 + }))
45 + .then(res => {
46 + upload_image.meta_id = res.data.data.meta_id;
47 + lock_btn.value = false; // 头像上传完成, 打开锁
48 + })
49 + .catch(err => {
50 + console.error(err);
51 + })
52 + } else {
53 + console.warn(res);
54 + Toast({
55 + icon: 'close',
56 + message: res.data.msg
57 + });
58 + }
59 + })
60 + .catch(err => {
61 + console.error(err);
62 + Toast({
63 + icon: 'close',
64 + message: res.data.msg
65 + });
66 + })
67 + } else {
68 + console.warn(res);
69 + }
70 + })
71 + .catch(err => {
72 + console.error(err);
73 + })
74 + };
75 + const beforeDelete = () => { // 删除图片回调
76 + metaId = '';
77 + upload_image.meta_id = '';
78 + return true;
79 + }
80 +
81 + return {
82 + lock_btn,
83 + fileList,
84 + upload_image,
85 + metaId,
86 + afterRead,
87 + beforeDelete
88 + }
89 +}
...\ No newline at end of file ...\ No newline at end of file
...@@ -117,11 +117,11 @@ export default [{ ...@@ -117,11 +117,11 @@ export default [{
117 }, 117 },
118 children: [] 118 children: []
119 }, { 119 }, {
120 - path: '/me/addUser', 120 + path: '/me/handleUser',
121 - name: '新增儿童', 121 + name: '新增/编辑儿童',
122 - component: () => import('./views/me/addUser.vue'), 122 + component: () => import('./views/me/handleUser.vue'),
123 meta: { 123 meta: {
124 - title: '新增儿童' 124 + title: '儿童信息'
125 }, 125 },
126 children: [] 126 children: []
127 }, { 127 }, {
......
...@@ -7,7 +7,9 @@ import qs from 'Qs' ...@@ -7,7 +7,9 @@ import qs from 'Qs'
7 axios.interceptors.request.use( 7 axios.interceptors.request.use(
8 config => { 8 config => {
9 // 发送请求前 9 // 发送请求前
10 - if (config.method === 'post') { 10 + if (config.method === 'post' &&
11 + (config.url.indexOf('a=upload') === -1 && config.url.indexOf('upload.qiniup.com') === -1)) // 上传相关接口需要屏蔽掉
12 + {
11 // POST PHP需要修改数据格式 13 // POST PHP需要修改数据格式
12 config.data = qs.stringify(config.data) 14 config.data = qs.stringify(config.data)
13 } 15 }
......
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
3 <p style="color: #713610; font-size: 1.25rem; padding: 1rem; text-align: center; font-weight: bold;">请录入儿童的信息</p> 3 <p style="color: #713610; font-size: 1.25rem; padding: 1rem; text-align: center; font-weight: bold;">请录入儿童的信息</p>
4 <div style=""> 4 <div style="">
5 <van-config-provider :theme-vars="themeVars"> 5 <van-config-provider :theme-vars="themeVars">
6 - <van-form @submit="onSubmit"> 6 + <van-form>
7 <van-cell-group inset> 7 <van-cell-group inset>
8 <van-field v-model="user_info.kindergarten" name="幼儿园" label="幼儿园" placeholder="" disabled /> 8 <van-field v-model="user_info.kindergarten" name="幼儿园" label="幼儿园" placeholder="" disabled />
9 - <van-field v-model="user_info.job" name="儿童姓名" label="儿童姓名" placeholder="请输入儿童姓名" /> 9 + <van-field v-model="user_info.name" name="儿童姓名" label="儿童姓名" placeholder="请输入儿童姓名" />
10 <van-row style="padding: 2vh 0;"> 10 <van-row style="padding: 2vh 0;">
11 <van-col span="7"><span style="font-size: 14px; color: #323233; margin-left: 2vh;">儿童头像</span></van-col> 11 <van-col span="7"><span style="font-size: 14px; color: #323233; margin-left: 2vh;">儿童头像</span></van-col>
12 <van-col span="17"><span style="font-size: 12px; color: #B0B0B0;">请上传一张清晰的儿童照片</span></van-col> 12 <van-col span="17"><span style="font-size: 12px; color: #B0B0B0;">请上传一张清晰的儿童照片</span></van-col>
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
19 </van-cell-group> 19 </van-cell-group>
20 <div style="margin: 2vh;"> 20 <div style="margin: 2vh;">
21 <van-button v-if="lock_btn" loading type="primary" loading-text="上传中..." style="width: 100%;" round></van-button> 21 <van-button v-if="lock_btn" loading type="primary" loading-text="上传中..." style="width: 100%;" round></van-button>
22 - <van-button v-else @click="saveInfo" :disabled="lock_btn" type="primary" native-type="submit" style="width: 100%;" round>保存</van-button> 22 + <van-button v-else @click="validForm" :disabled="lock_btn" type="primary" native-type="submit" style="width: 100%;" round>保存</van-button>
23 </div> 23 </div>
24 </van-form> 24 </van-form>
25 </van-config-provider> 25 </van-config-provider>
...@@ -28,13 +28,16 @@ ...@@ -28,13 +28,16 @@
28 </template> 28 </template>
29 29
30 <script setup> 30 <script setup>
31 -import { v4 as uuidv4 } from 'uuid'; 31 +import { useUpload } from '@/composables/useUpload.js'
32 +
32 import { ref, reactive, onMounted } from 'vue' 33 import { ref, reactive, onMounted } from 'vue'
33 import { useRoute, useRouter } from 'vue-router' 34 import { useRoute, useRouter } from 'vue-router'
34 import axios from '@/utils/axios'; 35 import axios from '@/utils/axios';
35 import $ from 'jquery' 36 import $ from 'jquery'
36 import { Toast } from 'vant'; 37 import { Toast } from 'vant';
37 38
39 +const { lock_btn, fileList, upload_image, metaId, afterRead, beforeDelete } = useUpload(); // 上传图片模块
40 +
38 const $route = useRoute(); 41 const $route = useRoute();
39 const $router = useRouter(); 42 const $router = useRouter();
40 43
...@@ -44,88 +47,24 @@ const themeVars = { ...@@ -44,88 +47,24 @@ const themeVars = {
44 buttonPrimaryColor: '#713610', 47 buttonPrimaryColor: '#713610',
45 }; 48 };
46 49
47 -const onSubmit = (values) => { 50 +// 验证输入项
48 - // console.log('submit', values); 51 +const validForm = () => {
52 + // if (!user_info.name) {
53 + // Toast.fail('儿童姓名不能为空')
54 + // return false;
55 + // }
56 + // if (!fileList.value.length) {
57 + // Toast.fail('儿童头像不能为空')
58 + // return false;
59 + // }
60 + saveInfo()
49 }; 61 };
50 62
51 -// 图片模块
52 -let lock_btn = ref(false); // 保存按钮锁
53 -let fileList = ref([]);
54 -let upload_image = reactive({ meta_id: '' });
55 -const afterRead = (res) => {
56 - lock_btn.value = true; // 上传开始, 不能保存
57 - let affix = uuidv4();
58 - // let affix = uuid();
59 - // 此时可以自行将文件上传至服务器
60 - let dataURL = res.content;
61 - let base64url = dataURL.slice(dataURL.indexOf(',') + 1); // 截取前缀的base64 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAnoAAAJeCAYAA.......
62 - //TODO: 获取七牛token
63 - axios.post('/srv/?f=shzl_comment&a=upload', {
64 - filename: `${affix}_${res.file.name}`,
65 - file: base64url
66 - })
67 - .then(res => {
68 - if (res.statusText === 'OK') {
69 - let config = {
70 - headers: {
71 - 'Content-Type': 'application/octet-stream',
72 - 'Authorization': 'UpToken ' + res.data.token, // UpToken后必须有一个 ' '(空格)
73 - }
74 - }
75 - // 上传七牛服务器
76 - axios.post('http://upload.qiniup.com/putb64/-1/key/' + res.data.key, base64url, config)
77 - .then(res => {
78 - if (res.data.filekey) {
79 - let info = res.data;
80 - // TODO: 保存图片返回ID
81 - axios.post('/srv/?f=shzl_comment&a=upload&t=save_file', {
82 - format: info.image_info.format,
83 - hash: info.hash,
84 - height: info.image_info.height,
85 - width: info.image_info.width,
86 - filekey: info.filekey,
87 - })
88 - .then(res => {
89 - upload_image.meta_id = res.data.data.meta_id;
90 - lock_btn.value = false; // 头像上传完成, 打开锁
91 - })
92 - .catch(err => {
93 - console.error(err);
94 - })
95 - } else {
96 - console.warn(res);
97 - Toast({
98 - icon: 'close',
99 - message: res.data.msg
100 - });
101 - }
102 - })
103 - .catch(err => {
104 - console.error(err);
105 - Toast({
106 - icon: 'close',
107 - message: res.data.msg
108 - });
109 - })
110 - } else {
111 - console.warn(res);
112 - }
113 - })
114 - .catch(err => {
115 - console.error(err);
116 - })
117 -};
118 -const beforeDelete = () => { // 删除图片回调
119 - user_info.meta_id = '';
120 - upload_image.meta_id = '';
121 - return true;
122 -}
123 -
124 let user_info = reactive({ 63 let user_info = reactive({
125 kg_id: $route.query.kg_id, 64 kg_id: $route.query.kg_id,
126 kindergarten: $route.query.kg_name, 65 kindergarten: $route.query.kg_name,
127 name: '', 66 name: '',
128 - meta_id: '' 67 + meta_id: metaId.value
129 }); 68 });
130 69
131 onMounted(() => { 70 onMounted(() => {
...@@ -135,12 +74,11 @@ onMounted(() => { ...@@ -135,12 +74,11 @@ onMounted(() => {
135 74
136 // 保存用户信息 75 // 保存用户信息
137 const saveInfo = () => { 76 const saveInfo = () => {
138 - // TODO: 以前接口保存的是一个ID,看后端怎么处理, perf_avatar看样子是一个图片地址 77 + axios.post('/srv/?a=add_performer', {
139 - axios.post('/srv/?f=shzl_comment&a=user&t=edit', {
140 kg_id: user_info.kg_id, 78 kg_id: user_info.kg_id,
141 perf_name: user_info.name, 79 perf_name: user_info.name,
142 - // perf_avatar: upload_image.meta_id ? upload_image.meta_id : user_info.meta_id, 80 + perf_avatar: '',
143 - meta_id: upload_image.meta_id ? upload_image.meta_id : user_info.meta_id, 81 + meta_id: upload_image.meta_id ? upload_image.meta_id : metaId,
144 }) 82 })
145 .then(res => { 83 .then(res => {
146 if (res.data.code === 1) { 84 if (res.data.code === 1) {
...@@ -148,7 +86,7 @@ const saveInfo = () => { ...@@ -148,7 +86,7 @@ const saveInfo = () => {
148 message: '保存成功', 86 message: '保存成功',
149 duration: 1000, 87 duration: 1000,
150 onClose: () => { 88 onClose: () => {
151 - goBack(); 89 + $router.go(-1)
152 } 90 }
153 }); 91 });
154 } else { 92 } else {
......
1 +<template>
2 + <div class="add-user-page">
3 + <p class="title">请录入儿童的信息</p>
4 + <van-config-provider :theme-vars="themeVars">
5 + <van-form>
6 + <van-cell-group inset>
7 + <van-field v-model="user_info.kindergarten" name="幼儿园" label="幼儿园" placeholder="" disabled />
8 + <van-field v-model="user_info.name" name="儿童姓名" label="儿童姓名" placeholder="请输入儿童姓名" />
9 + <van-row class="upload-text">
10 + <van-col span="7"><span class="upload-text-1">儿童头像</span></van-col>
11 + <van-col span="17"><span class="upload-text-2">请上传一张清晰的儿童照片</span></van-col>
12 + </van-row>
13 + <van-row style="padding-bottom: 2vh;">
14 + <van-col span="16" offset="8">
15 + <van-uploader v-model="fileList" :after-read="afterRead" :before-delete="beforeDelete" :max-count="1" />
16 + </van-col>
17 + </van-row>
18 + </van-cell-group>
19 + <div style="margin: 2vh;">
20 + <van-button v-if="lock_btn" loading type="primary" loading-text="上传中..." style="width: 100%;" round>
21 + </van-button>
22 + <van-button v-else @click="validForm" :disabled="lock_btn" type="primary" native-type="submit"
23 + style="width: 100%;" round>保存</van-button>
24 + </div>
25 + </van-form>
26 + </van-config-provider>
27 + </div>
28 +</template>
29 +
30 +<script setup>
31 +import { useUpload } from '@/composables/useUpload.js'
32 +
33 +import { ref, reactive, onMounted } from 'vue'
34 +import { useRoute, useRouter } from 'vue-router'
35 +import axios from '@/utils/axios';
36 +import { Toast } from 'vant';
37 +
38 +const { lock_btn, fileList, upload_image, metaId, afterRead, beforeDelete } = useUpload(); // 上传图片模块
39 +
40 +const $route = useRoute();
41 +const $router = useRouter();
42 +
43 +// 自定义修改组件样式
44 +const themeVars = {
45 + buttonPrimaryBackground: '#F9D95C',
46 + buttonPrimaryBorderColor: '#F9D95C',
47 + buttonPrimaryColor: '#713610',
48 +};
49 +
50 +// 编辑状态
51 +if ($route.query.type === 'EDIT') {
52 + fileList.value.push({
53 + url: $route.query.avatar,
54 + isImage: true
55 + })
56 +}
57 +
58 +// 验证输入项
59 +const validForm = () => {
60 + if (!user_info.name) {
61 + Toast.fail('儿童姓名不能为空')
62 + return false;
63 + }
64 + if (!fileList.value.length) {
65 + Toast.fail('儿童头像不能为空')
66 + return false;
67 + }
68 + saveInfo()
69 +};
70 +
71 +let user_info = reactive({
72 + kg_id: $route.query.kg_id,
73 + kindergarten: $route.query.kg_name,
74 + name: $route.query.name,
75 + meta_id: metaId.value
76 +});
77 +
78 +// 保存用户信息
79 +const saveInfo = () => {
80 + let url = $route.query.type === 'Add' ? 'add_performer' : 'add_performer';
81 + axios.post(`/srv/?a=${url}`, {
82 + kg_id: user_info.kg_id,
83 + perf_name: user_info.name,
84 + perf_avatar: '',
85 + meta_id: upload_image.meta_id ? upload_image.meta_id : metaId,
86 + })
87 + .then(res => {
88 + if (res.data.code === 1) {
89 + Toast.success({
90 + message: '保存成功',
91 + duration: 1000,
92 + onClose: () => {
93 + $router.go(-1)
94 + }
95 + });
96 + } else {
97 + console.warn(res);
98 + Toast({
99 + icon: 'close',
100 + message: res.data.msg
101 + });
102 + }
103 + })
104 + .catch(err => {
105 + console.error(err);
106 + })
107 +}
108 +</script>
109 +
110 +<script>
111 +import mixin from 'common/mixin';
112 +
113 +export default {
114 + mixins: [mixin.init],
115 + data() {
116 + return {
117 +
118 + }
119 + },
120 + mounted() {
121 +
122 + },
123 + methods: {
124 +
125 + }
126 +}
127 +</script>
128 +
129 +<style lang="less" scoped>
130 +.add-user-page {
131 + padding: 1rem;
132 + .title {
133 + color: #713610;
134 + font-size: 1.25rem;
135 + padding: 1rem;
136 + text-align: center;
137 + font-weight: bold;
138 + }
139 + .upload-text {
140 + padding: 2vh 0;
141 + .upload-text-1 {
142 + font-size: 14px;
143 + color: #323233;
144 + margin-left: 2vh;
145 + }
146 + .upload-text-2 {
147 + font-size: 12px;
148 + color: #B0B0B0;
149 + }
150 + }
151 +}
152 +</style>
...\ No newline at end of file ...\ No newline at end of file
...@@ -4,8 +4,7 @@ ...@@ -4,8 +4,7 @@
4 <div class="info"> 4 <div class="info">
5 <van-row> 5 <van-row>
6 <van-col> 6 <van-col>
7 - <van-image round width="50" height="50" :src="userInfo.avatar" 7 + <van-image @click="handleUser('EDIT')" round width="50" height="50" :src="userInfo.avatar" style="padding-right: 1rem;" />
8 - style="padding-right: 1rem;" />
9 </van-col> 8 </van-col>
10 <van-col class="text-wrapper" span="18"> 9 <van-col class="text-wrapper" span="18">
11 <div> 10 <div>
...@@ -48,7 +47,7 @@ ...@@ -48,7 +47,7 @@
48 <my-button v-else type="custom" :custom-style="styleObject3">已认证</my-button> 47 <my-button v-else type="custom" :custom-style="styleObject3">已认证</my-button>
49 </div> 48 </div>
50 <div> 49 <div>
51 - <my-button type="custom" :custom-style="styleObject2" @on-click="goTo('/me/addUser')">新增儿童</my-button> 50 + <my-button type="custom" :custom-style="styleObject2" @on-click="handleUser('ADD')">新增儿童</my-button>
52 </div> 51 </div>
53 </div> 52 </div>
54 53
...@@ -229,6 +228,30 @@ const goTo = (path) => { ...@@ -229,6 +228,30 @@ const goTo = (path) => {
229 } 228 }
230 }) 229 })
231 } 230 }
231 +// 新增/编辑儿童信息
232 +const handleUser = (type) => {
233 + if (type === 'ADD') {
234 + $router.push({
235 + path: '/me/handleUser',
236 + query: {
237 + kg_id: userInfo.value.kg_id,
238 + kg_name: userInfo.value.kg_name,
239 + type
240 + }
241 + })
242 + } else {
243 + $router.push({
244 + path: '/me/handleUser',
245 + query: {
246 + avatar: userInfo.value.avatar,
247 + name: userInfo.value.name,
248 + kg_id: userInfo.value.kg_id,
249 + kg_name: userInfo.value.kg_name,
250 + type
251 + }
252 + })
253 + }
254 +}
232 255
233 // 自定义按钮颜色样式 256 // 自定义按钮颜色样式
234 const styleObject1 = reactive({ 257 const styleObject1 = reactive({
......