提交 958ed191 authored 作者: lidongxu's avatar lidongxu

'完成下班卡需要判断促销上报是否成功'

上级 96e38f31
...@@ -61,3 +61,12 @@ export function getPromotionPhotoRecordAPI(id) { ...@@ -61,3 +61,12 @@ export function getPromotionPhotoRecordAPI(id) {
url: `/activity/temporary/query/today/${id}` url: `/activity/temporary/query/today/${id}`
}) })
} }
// 促销员是否能下班判断(尝试提交审批通过后台判断响应正确即可调用下班打卡)
// id:促销员 id
export function getOnWorkCardStatusAPI(id) {
return request({
url: `/activity/temporary/core/reported/approve/submit/${id}`,
method: 'PUT'
})
}
\ No newline at end of file
促销员 ID:
促销任务上报 ID:
计划 ID:
\ No newline at end of file
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
{ {
"path": "pages/work/index", "path": "pages/work/index",
"style": { "style": {
"navigationBarTitleText": "今日销售记录" "navigationBarTitleText": "上传推广照片"
} }
}, },
{ {
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
<div class="line"> <div class="line">
<van-button class="btn_item" <van-button class="btn_item"
type="primary" type="primary"
v-if="onWorkRecord.clockInTime && !onWorkRecord.noonClockOutTime" v-if="onWorkRecord.clockInTime && !onWorkRecord.noonClockOutTime && !onWorkRecord.clockOutTime"
@click="attendanceClickFn(2)">午休卡</van-button> @click="attendanceClickFn(2)">午休卡</van-button>
<view class="clock_item" <view class="clock_item"
v-else-if="onWorkRecord.noonClockOutTime"> v-else-if="onWorkRecord.noonClockOutTime">
...@@ -105,7 +105,7 @@ ...@@ -105,7 +105,7 @@
fit="cover" fit="cover"
round /> round />
<view class="mark"> <view class="mark">
<view class="mark_text">午休卡-已打</view> <view class="mark_text">下班卡-已打</view>
<view class="mark_time">{{ onWorkRecord.clockOutTime }}</view> <view class="mark_time">{{ onWorkRecord.clockOutTime }}</view>
</view> </view>
</view> </view>
...@@ -119,7 +119,7 @@ ...@@ -119,7 +119,7 @@
<script> <script>
import { getAttendanceDetailAPI, addAttendanceAPI, getAttendanceListAPI, getProStoreAPI, getPlanListAPI, getOnWorkCardAPI, createOnWorkPlanAPI, getOnWorkRecordAPI } from '@/api' import { getAttendanceDetailAPI, addAttendanceAPI, getAttendanceListAPI, getProStoreAPI, getPlanListAPI, getOnWorkCardAPI, createOnWorkPlanAPI, getOnWorkRecordAPI, getOnWorkCardStatusAPI } from '@/api'
import { checkStartLessEndTime, parseTime, isSameDay, zeroTo24, checkTimeIsBetween } from '@/utils/common' import { checkStartLessEndTime, parseTime, isSameDay, zeroTo24, checkTimeIsBetween } from '@/utils/common'
import { uploadFile } from '@/api/common/upload' import { uploadFile } from '@/api/common/upload'
import QQMapWX from '../../libs/qqmap-wx-jssdk1.2/qqmap-wx-jssdk.js' import QQMapWX from '../../libs/qqmap-wx-jssdk1.2/qqmap-wx-jssdk.js'
...@@ -127,6 +127,7 @@ import QQMapWX from '../../libs/qqmap-wx-jssdk1.2/qqmap-wx-jssdk.js' ...@@ -127,6 +127,7 @@ import QQMapWX from '../../libs/qqmap-wx-jssdk1.2/qqmap-wx-jssdk.js'
import config from '@/config' import config from '@/config'
import storage from '@/utils/storage' import storage from '@/utils/storage'
import constant from '@/utils/constant' import constant from '@/utils/constant'
import { v4 as uuidv4 } from 'uuid'
export default { export default {
data() { data() {
return { return {
...@@ -190,7 +191,6 @@ export default { ...@@ -190,7 +191,6 @@ export default {
}); });
qqmapsdk.reverseGeocoder({ qqmapsdk.reverseGeocoder({
success: function (ress) { success: function (ress) {
console.log('地址', ress)
const { result: { ad_info: { province, city, district, location: { lat, lng } }, formatted_addresses: { recommend } } } = ress const { result: { ad_info: { province, city, district, location: { lat, lng } }, formatted_addresses: { recommend } } } = ress
_this.address = recommend; _this.address = recommend;
_this.lat = lat _this.lat = lat
...@@ -242,7 +242,24 @@ export default { ...@@ -242,7 +242,24 @@ export default {
this.$modal.msgError('请选择计划') this.$modal.msgError('请选择计划')
return return
} }
// 判断是否到了上班打卡时间
if (type === 1) {
const { clockInTime } = planObj
const time = parseTime(new Date(clockInTime), '{h}:{m}:{s}')
const isClock = checkStartLessEndTime(time, parseTime(new Date(), '{h}:{m}:{s}'))
if (!isClock) {
this.$modal.msgError('未到上班打卡时间')
return
}
}
// 判断是否能下班
if (type === 4) {
// 下班先提交促销上班看看是否通过后台校验
await getOnWorkCardStatusAPI(this.onWorkRecord.reportedId)
}
// 前置条件过滤完毕,走打卡流程
const photoUrl = await this.pickerPhoto(type) // 拍照 const photoUrl = await this.pickerPhoto(type) // 拍照
const { id, name } = this.$store.getters.user const { id, name } = this.$store.getters.user
...@@ -260,16 +277,22 @@ export default { ...@@ -260,16 +277,22 @@ export default {
clockCity: this.addressObj.city, // 城市 clockCity: this.addressObj.city, // 城市
clockArea: this.addressObj.area, // 区域 clockArea: this.addressObj.area, // 区域
} }
try { try {
// 打卡
const res = await getOnWorkCardAPI(attObj)
if (type === 1) { if (type === 1) {
// 创建上报记录 // 创建上报记录-才算完成打卡
await this.createOnWorkPlanFn() const res = await createOnWorkPlanAPI({
activityReportedId: planObj.id,
temporaryId: this.$store.getters.user.id, // 促销员 ID
temporaryName: this.$store.getters.user.name, // 促销员姓名
})
console.log(res)
} }
// 打卡
// await getOnWorkCardAPI(attObj)
this.$modal.msgSuccess('打卡成功') this.$modal.msgSuccess('打卡成功')
console.log('考勤打卡记录', res) wx.showTabBar({
animation: true
})
} catch (err) { } catch (err) {
this.$modal.msgError(err.msg) this.$modal.msgError(err.msg)
} }
...@@ -296,47 +319,42 @@ export default { ...@@ -296,47 +319,42 @@ export default {
success: async (res) => { success: async (res) => {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片 // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
const tempFilePaths = res.tempFilePaths; const tempFilePaths = res.tempFilePaths;
console.log(tempFilePaths[0]); // 输出图片路径 const date = new Date()
const result = await uploadFile(`planAndPhoto/${this.phone}/clock/${type}.png`, tempFilePaths[0]) const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const result = await uploadFile(`clockAndPromotion/${year}-${month}/${day}/${this.phone}/clock/${uuidv4()}.png`, tempFilePaths[0])
resolve(result) resolve(result)
} }
}); });
}) })
}, },
// 创建活动上报记录
async createOnWorkPlanFn() {
const res = await createOnWorkPlanAPI({
temporaryId: this.$store.getters.user.id, // 促销员 ID
temporaryName: this.$store.getters.user.name, // 促销员姓名
// "tgscPhotoUrls":[],
// "tgscChangePhotoUrls":[],
// "tghdPhotoUrls":[],
// "tghdChangePhotoUrls":[],
// "tgcjPhotoUrls":[],
// "tgcjChangePhotoUrls":[]
})
console.log(res)
},
// 获取促销员任务列表 // 获取促销员任务列表
async getOnWorkRecordFn() { async getOnWorkRecordFn() {
const res = await getOnWorkRecordAPI(this.$store.getters.user.id) const res = await getOnWorkRecordAPI(this.$store.getters.user.id)
if (!res.data) return this.isLoading = false // 没有打过卡
if (!res.data) {
wx.hideTabBar()
return this.isLoading = false
}
this.planList = [res.data.storeName] this.planList = [res.data.storeName]
this.plan = res.data.storeName this.plan = res.data.storeName
// 上班打卡时间格式化成时分秒 // 上班打卡时间格式化成时分秒
if (res.data.clockInTime) { if (res.data.clockInTime) {
res.data.clockInTime = parseTime(res.data.clockInTime, '{h}:{m}:{s}') res.data.clockInTime = parseTime(new Date(res.data.clockInTime), '{h}:{i}:{s}')
} }
if (res.data.noonClockOutTime) { if (res.data.noonClockOutTime) {
res.data.noonClockOutTime = parseTime(res.data.noonClockOutTime, '{h}:{m}:{s}') res.data.noonClockOutTime = parseTime(new Date(res.data.noonClockOutTime), '{h}:{i}:{s}')
} }
if (res.data.noonClockInTime) { if (res.data.noonClockInTime) {
res.data.noonClockInTime = parseTime(res.data.noonClockInTime, '{h}:{m}:{s}') res.data.noonClockInTime = parseTime(new Date(res.data.noonClockInTime), '{h}:{i}:{s}')
} }
if (res.data.clockOutTime) { if (res.data.clockOutTime) {
res.data.clockOutTime = parseTime(res.data.clockOutTime, '{h}:{m}:{s}') res.data.clockOutTime = parseTime(new Date(res.data.clockOutTime), '{h}:{i}:{s}')
} }
this.onWorkRecord = res.data this.onWorkRecord = res.data
console.log(this.onWorkRecord)
this.isLoading = false this.isLoading = false
} }
} }
...@@ -391,6 +409,7 @@ export default { ...@@ -391,6 +409,7 @@ export default {
width: 250rpx; width: 250rpx;
height: 250rpx; height: 250rpx;
border-radius: 50%; border-radius: 50%;
font-size: 32rpx;
} }
::v-deep .van-button--primary { ::v-deep .van-button--primary {
...@@ -420,9 +439,10 @@ export default { ...@@ -420,9 +439,10 @@ export default {
align-items: center; align-items: center;
color: white; color: white;
flex-direction: column; flex-direction: column;
font-size: 32rpx;
.mark_time { .mark_time {
font-size: 24rpx; font-size: 26rpx;
} }
} }
......
...@@ -103,6 +103,7 @@ export default { ...@@ -103,6 +103,7 @@ export default {
// 调用自己后台登录接口 // 调用自己后台登录接口
const loginRes = await this.$store.dispatch('Login', { phoneNumber, openId }) const loginRes = await this.$store.dispatch('Login', { phoneNumber, openId })
storage.set(constant.loginPhone, phoneNumber)
// 手机号从未注册过-需要填写资料完成注册 // 手机号从未注册过-需要填写资料完成注册
if (loginRes.code === 3004) { if (loginRes.code === 3004) {
...@@ -111,7 +112,6 @@ export default { ...@@ -111,7 +112,6 @@ export default {
}, 1500) }, 1500)
} else { } else {
// 之前注册提交过资料,直接登录成功去首页 // 之前注册提交过资料,直接登录成功去首页
storage.set(constant.loginPhone, phoneNumber)
this.$tab.reLaunch('/pages/home/index') this.$tab.reLaunch('/pages/home/index')
} }
......
<template> <template>
<view class="normal-register-container"> <view class="normal-register-container">
<!-- 基础表单校验 --> <!-- 基础表单校验 -->
<uni-forms ref="valiForm" <uni-forms ref="valiForm"
:rules="rules" :rules="rules"
...@@ -44,25 +43,22 @@ ...@@ -44,25 +43,22 @@
</view> </view>
</uni-forms-item> </uni-forms-item>
<button class="bg-blue register-btn" <button class="bg-blue register-btn"
@click="submit('valiForm')">注册完成</button> @click="submit('valiForm')">提交注册</button>
<view>本手机号第一次注册,请补充资料完成注册登录</view>
</uni-forms> </uni-forms>
<view class="reg-info">{{ phone }} 首次注册,补充资料完成注册</view>
</view> </view>
</template> </template>
<script> <script>
import { mapGetters } from 'vuex'
import { uploadFile, submitUserInfoAPI, loginAPI } from '../api' import { uploadFile, submitUserInfoAPI, loginAPI } from '../api'
import { v4 as uuidv4 } from 'uuid'
import storage from '../utils/storage' import storage from '../utils/storage'
import constant from '../utils/constant' import constant from '../utils/constant'
export default { export default {
created() { created() {
this.phone = storage.get(constant.loginPhone) this.phone = storage.get(constant.loginPhone)
this.openId = storage.get(constant.loginOpenId) this.openId = storage.get(constant.loginOpenId)
// this.formData.avatarUrl = this.user.avatarUrl
// this.formData.name = this.user.nickName
}, },
data() { data() {
return { return {
...@@ -93,25 +89,24 @@ export default { ...@@ -93,25 +89,24 @@ export default {
} }
} }
}, },
computed: {
...mapGetters(['user'])
},
methods: { methods: {
// 选择了头像 // 选择了头像
async chooseavatarFn(obj) { async chooseavatarFn(obj) {
this.formData.avatarUrl = await uploadFile(`avatarAndIdentify/${this.phone}/${this.phone}-avatar.png`, obj.detail.avatarUrl) this.formData.avatarUrl = await uploadFile(`avatarAndIdentify/${this.phone}/${uuidv4()}-avatar.png`, obj.detail.avatarUrl)
}, },
// 选择了身份证 // 选择了身份证-正面
async selectIdenPhotoFrontFn(obj) { async selectIdenPhotoFrontFn(obj) {
this.formData.idenFrontUrl = await uploadFile(`avatarAndIdentify/${this.phone}/${this.phone}-frontId.png`, obj.tempFiles[0].path) this.formData.idenFrontUrl = await uploadFile(`avatarAndIdentify/${this.phone}/${uuidv4()}-frontId.png`, obj.tempFiles[0]?.path)
}, },
// 选择了身份证-背面
async selectIdenPhotoBackFn(obj) { async selectIdenPhotoBackFn(obj) {
this.formData.idenBackUrl = await uploadFile(`avatarAndIdentify/${this.phone}/${this.phone}-backId.png`, obj.tempFiles[0].path) this.formData.idenBackUrl = await uploadFile(`avatarAndIdentify/${this.phone}/${uuidv4()}-backId.png`, obj.tempFiles[0]?.path)
}, },
// 注册完成
submit(ref) { submit(ref) {
this.$refs[ref].validate().then(async res => { this.$refs[ref].validate().then(async res => {
// TODO: 后面需要后台提供促销员信息注册接口 // 手机号首次需要调用此接口注册-拿到后台 token(以后调用后台登录接口才能通过拿到 token)
const result = await submitUserInfoAPI({ await submitUserInfoAPI({
avatarUrl: this.formData.avatarUrl, avatarUrl: this.formData.avatarUrl,
openId: storage.get(constant.loginOpenId), openId: storage.get(constant.loginOpenId),
name: this.formData.name, name: this.formData.name,
...@@ -128,13 +123,12 @@ export default { ...@@ -128,13 +123,12 @@ export default {
this.$store.commit('SET_TOKEN', data.token) this.$store.commit('SET_TOKEN', data.token)
this.$store.commit('SET_USER', data.user) this.$store.commit('SET_USER', data.user)
uni.showToast({ this.$modal.msgSuccess("注册成功")
title: `注册成功` // 申请地理位置权限
}) // await this.$store.dispatch('GetLocation')
await this.$store.dispatch('GetLocation')
this.$tab.switchTab('/pages/home/index') this.$tab.switchTab('/pages/home/index')
}).catch(err => { }).catch(err => {
console.log('err', err); console.log('err', err)
}) })
} }
} }
...@@ -199,5 +193,12 @@ page { ...@@ -199,5 +193,12 @@ page {
.register-btn { .register-btn {
border-radius: 50rpx; border-radius: 50rpx;
} }
// 注册提示信息
.reg-info {
text-align: center;
margin-top: 30rpx;
font-size: 30rpx;
}
} }
</style> </style>
...@@ -10,6 +10,7 @@ export default { ...@@ -10,6 +10,7 @@ export default {
mounted() { mounted() {
setTimeout(() => { setTimeout(() => {
this.$tab.redirectTo('/pages/login') this.$tab.redirectTo('/pages/login')
wx.hideTabBar()
}, 2000) }, 2000)
} }
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<view class="store_name">{{ storeName }}</view> <view class="store_name">{{ storeName }}</view>
</view> </view>
<view class="title title_back">推广试吃照片(最少 4 张)</view> <view class="title title_back">推广试吃照片(最少 4 张)</view>
<van-uploader preview-size="170rpx" <van-uploader preview-size="187.5rpx"
name="img" name="img"
accept="image" accept="image"
:capture="['camera']" :capture="['camera']"
...@@ -12,14 +12,14 @@ ...@@ -12,14 +12,14 @@
@after-read="afterTry" @after-read="afterTry"
@delete="deleteTry" /> @delete="deleteTry" />
<view class="title title_back">推广互动照片(最少 4 张)</view> <view class="title title_back">推广互动照片(最少 4 张)</view>
<van-uploader preview-size="170rpx" <van-uploader preview-size="187.5rpx"
accept="image" accept="image"
:capture="['camera']" :capture="['camera']"
:file-list="afterInterFileList" :file-list="afterInterFileList"
@after-read="afterInter" @after-read="afterInter"
@delete="deleteInter" /> @delete="deleteInter" />
<view class="title title_back">推广成交照片(最少 4 张)</view> <view class="title title_back">推广成交照片(最少 4 张)</view>
<van-uploader preview-size="170rpx" <van-uploader preview-size="187.5rpx"
accept="image" accept="image"
:capture="['camera']" :capture="['camera']"
:file-list="afterDealFileList" :file-list="afterDealFileList"
...@@ -50,21 +50,21 @@ export default { ...@@ -50,21 +50,21 @@ export default {
// 获取促销员任务列表 // 获取促销员任务列表
async getOnWorkRecordFn() { async getOnWorkRecordFn() {
const res = await getOnWorkRecordAPI(this.$store.getters.user.id) const res = await getOnWorkRecordAPI(this.$store.getters.user.id)
this.storeName = res.data.storeName this.storeName = res.data?.storeName
this.activityReportedId = res.data.reportedId // 活动上报 ID this.activityReportedId = res.data?.reportedId // 活动上报 ID
}, },
// 获取推广照片列表 // 获取推广照片列表
async getPromotionPhotoFn() { async getPromotionPhotoFn() {
const res = await getPromotionPhotoRecordAPI(this.$store.getters.user.id) const res = await getPromotionPhotoRecordAPI(this.$store.getters.user.id)
this.afterTryFileList = res.data.tgscPhotoUrls ? res.data.tgscPhotoUrls?.map(o => ({ this.afterTryFileList = res.data ? res.data.tgscPhotoUrls?.map(o => ({
url: o, url: o,
type: 'image' type: 'image'
})) : [] })) : []
this.afterInterFileList = res.data.tghdPhotoUrls ? res.data.tghdPhotoUrls?.map(o => ({ this.afterInterFileList = res.data ? res.data.tghdPhotoUrls?.map(o => ({
url: o, url: o,
type: 'image' type: 'image'
})) : [] })) : []
this.afterDealFileList = res.data.tgcjPhotoUrls ? res.data.tgcjPhotoUrls?.map(o => ({ this.afterDealFileList = res.data ? res.data.tgcjPhotoUrls?.map(o => ({
url: o, url: o,
type: 'image' type: 'image'
})) : [] })) : []
...@@ -121,7 +121,7 @@ export default { ...@@ -121,7 +121,7 @@ export default {
console.log(res) console.log(res)
}, },
deleteTry(event) { deleteTry(event) {
this.afterTryFileList.splice(event.detail.index, 1) this.afterTryFileList.splice(event.detail.index, 1)
this.submitPhoto() this.submitPhoto()
}, },
// 前端删除照片 // 前端删除照片
...@@ -156,6 +156,24 @@ export default { ...@@ -156,6 +156,24 @@ export default {
} }
} }
::v-deep .van-uploader {
width: 100%;
.van-uploader__wrapper {
width: 100%;
.van-uploader__preview {
margin: 0 !important;
}
.van-uploader__upload {
margin: 0 !important;
}
}
}
.wrap { .wrap {
background-color: white; background-color: white;
min-height: 100vh; min-height: 100vh;
...@@ -163,14 +181,14 @@ export default { ...@@ -163,14 +181,14 @@ export default {
flex-direction: column; flex-direction: column;
.store_name { .store_name {
font-size: 30rpx; font-size: 28rpx;
display: inline-block; display: inline-block;
color: #7b7b7b; color: #7b7b7b;
padding-left: 30rpx; padding-left: 30rpx;
} }
.title { .title {
font-size: 28rpx; font-size: 26rpx;
padding: 10px; padding: 10px;
} }
......
import storage from '@/utils/storage' import storage from '@/utils/storage'
import constant from '@/utils/constant' import constant from '@/utils/constant'
import { reverseGeocoding } from '@/api'
import $modal from '@/plugins/modal' import $modal from '@/plugins/modal'
const location = { const location = {
...@@ -17,7 +16,7 @@ const location = { ...@@ -17,7 +16,7 @@ const location = {
}, },
actions: { actions: {
// 获取本机位置信息 // 获取本机位置信息(暂时用不上了-使用腾讯 SDK 直接获取位置)
GetLocation({ commit }) { GetLocation({ commit }) {
// getLocation 获取经纬度 // getLocation 获取经纬度
// chooseLocation 让用户在地图手选位置 // chooseLocation 让用户在地图手选位置
......
...@@ -99,7 +99,10 @@ export function parseTime(time, pattern) { ...@@ -99,7 +99,10 @@ export function parseTime(time, pattern) {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) { if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time) time = parseInt(time)
} else if (typeof time === 'string') { } else if (typeof time === 'string') {
time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
// 移除时区信息,将时间字符串转换为 UTC 时间
time = time.replace('T', ' ').replace(/\.\d+\+00:00$/, '');
date = new Date(Date.UTC(...time.split(/[- :]/)));
} }
if ((typeof time === 'number') && (time.toString().length === 10)) { if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000 time = time * 1000
......
...@@ -51,7 +51,6 @@ const request = config => { ...@@ -51,7 +51,6 @@ const request = config => {
toast(msg) toast(msg)
reject('500') reject('500')
} else if (code !== 200) { } else if (code !== 200) {
toast(msg)
if (code === 3017) { if (code === 3017) {
console.log('登录状态 token 过期了') console.log('登录状态 token 过期了')
// 重新登录 // 重新登录
...@@ -59,9 +58,10 @@ const request = config => { ...@@ -59,9 +58,10 @@ const request = config => {
// 重新请求 // 重新请求
request(config) request(config)
} else if (code === 3004) { } else if (code === 3004) {
// 账号未注册(在登录页面有跳转判断 // 账号未注册(在登录页面有跳转判断)
resolve(res) resolve(res)
} else { } else {
toast(msg)
reject(code) reject(code)
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论