报工添加了手动录入能力

This commit is contained in:
2026-05-05 19:49:11 +08:00
parent acf0048bf1
commit 04c84a3ed3
2 changed files with 103 additions and 6 deletions

View File

@@ -201,10 +201,37 @@
:closable="false" :closable="false"
style="margin-bottom: 20px;"> style="margin-bottom: 20px;">
</el-alert> </el-alert>
<el-alert
v-if="workPlaceLocateError && !form.reportId"
title="定位获取失败"
type="info"
:closable="false"
style="margin-bottom: 20px;">
<div slot="default">
<p style="margin: 5px 0; font-weight: bold;">如果浏览器无法获取定位,请按以下步骤操作:</p>
<ol style="margin: 5px 0; padding-left: 20px; line-height: 1.8;">
<li>在浏览器地址栏输入:<code style="background: #f0f0f0; padding: 2px 6px; border-radius: 3px;">edge://flags/#unsafely-treat-insecure-origin-as-secure</code>(Edge) 或 <code style="background: #f0f0f0; padding: 2px 6px; border-radius: 3px;">chrome://flags/#unsafely-treat-insecure-origin-as-secure</code>(Chrome)</li>
<li>找到选项 <strong>"Insecure origins treated as secure"</strong></li>
<li>输入您的站点地址:<code style="background: #f0f0f0; padding: 2px 6px; border-radius: 3px;">http://49.232.154.205</code>,然后设置为 <strong>Enabled</strong></li>
<li>重启浏览器,再尝试点击重新获取定位按钮</li>
</ol>
</div>
</el-alert>
<el-form ref="form" :model="form" :rules="rules" label-width="96px"> <el-form ref="form" :model="form" :rules="rules" label-width="96px">
<el-form-item label="工作地点" prop="workPlace"> <el-form-item label="工作地点" prop="workPlace">
<el-input v-model="form.workPlace" placeholder="请输入工作地点"/> <el-input
v-model="form.workPlace"
:placeholder="workPlaceLoading ? '正在获取定位…' : '请输入工作地点或点击「重新获取定位」'"
>
<el-button
slot="append"
icon="el-icon-location-outline"
:loading="workPlaceLoading"
@click="refreshWorkPlace"
>重新获取定位</el-button>
</el-input>
<div v-if="workPlaceLocateError" class="work-place-error">{{ workPlaceLocateError }}</div>
</el-form-item> </el-form-item>
<el-form-item label="是否出差" prop="isTrip"> <el-form-item label="是否出差" prop="isTrip">
<el-radio-group v-model="form.isTrip"> <el-radio-group v-model="form.isTrip">
@@ -275,12 +302,19 @@ import { listDept } from "@/api/system/dept";
import { listUser } from "@/api/system/user"; import { listUser } from "@/api/system/user";
import ProjectSelect from "@/components/fad-service/ProjectSelect"; import ProjectSelect from "@/components/fad-service/ProjectSelect";
import ProjectReportDetail from "@/views/oa/project/report/components/ProjectReportDetail.vue"; import ProjectReportDetail from "@/views/oa/project/report/components/ProjectReportDetail.vue";
import {
EMPTY_GEOCODE,
geolocationUserMessage,
resolveWorkPlaceFromBrowser
} from "@/utils/geolocationWorkPlace";
export default { export default {
name: "ProjectReport", name: "ProjectReport",
components: {ProjectReportDetail, ProjectSelect}, components: {ProjectReportDetail, ProjectSelect},
data() { data() {
return { return {
workPlaceLoading: false,
workPlaceLocateError: "",
// 按钮loading // 按钮loading
buttonLoading: false, buttonLoading: false,
detailVisible: false, detailVisible: false,
@@ -356,6 +390,50 @@ export default {
this.getUserList(); this.getUserList();
}, },
methods: { methods: {
/**
* @param {{ silent?: boolean, force?: boolean }} options
*/
async syncWorkPlaceFromGeolocation(options = {}) {
const silent = !!options.silent;
const force = !!options.force;
if (!force && this.form && this.form.reportId) {
return;
}
this.workPlaceLoading = true;
this.workPlaceLocateError = "";
try {
const text = await resolveWorkPlaceFromBrowser();
this.$set(this.form, "workPlace", text);
if (!silent) {
this.$modal.msgSuccess("已根据定位更新工作地点");
}
} catch (e) {
console.error("[projectReport] 工作地点定位失败", e);
const msg = geolocationUserMessage(e);
this.workPlaceLocateError = msg;
this.$set(this.form, "workPlace", undefined);
const isBrowserGeoError =
e &&
(e.code === 1 ||
e.code === 2 ||
e.code === 3 ||
e.message === "BROWSER_UNSUPPORTED" ||
e.message === EMPTY_GEOCODE);
if (isBrowserGeoError) {
this.$modal.msgWarning(msg);
}
} finally {
this.workPlaceLoading = false;
this.$nextTick(() => {
if (this.$refs.form) {
this.$refs.form.validateField("workPlace");
}
});
}
},
refreshWorkPlace() {
this.syncWorkPlaceFromGeolocation({ silent: false, force: true });
},
/** 查询详情 */ /** 查询详情 */
openDetail(row) { openDetail(row) {
getProjectReport(row.reportId).then(response => { getProjectReport(row.reportId).then(response => {
@@ -369,11 +447,14 @@ export default {
this.reset(); this.reset();
this.open = true; this.open = true;
this.title = "补录项目报工"; this.title = "补录项目报工";
this.$nextTick(() => {
this.syncWorkPlaceFromGeolocation({ silent: true, force: false });
});
}, },
/** 检查今日报工 */ /** 检查今日报工 */
checkTodayReport() { checkTodayReport() {
getTodayProjectReport().then(response => { return getTodayProjectReport().then(response => {
if (response.data && response.data.reportId) { if (response.data && response.data.reportId) {
this.hasTodayReport = true; this.hasTodayReport = true;
this.todayReportId = response.data.reportId; this.todayReportId = response.data.reportId;
@@ -426,6 +507,8 @@ export default {
}, },
// 表单重置 // 表单重置
reset() { reset() {
this.workPlaceLoading = false;
this.workPlaceLocateError = "";
this.form = { this.form = {
reportId: undefined, reportId: undefined,
handler: undefined, handler: undefined,
@@ -472,9 +555,15 @@ export default {
handleAdd() { handleAdd() {
this.reset(); this.reset();
this.suppVisible = false; this.suppVisible = false;
this.checkTodayReport();
this.open = true;
this.title = "添加项目报工"; this.title = "添加项目报工";
this.checkTodayReport().finally(() => {
this.open = true;
this.$nextTick(() => {
if (!this.form.reportId) {
this.syncWorkPlaceFromGeolocation({ silent: true, force: false });
}
});
});
}, },
/** 修改按钮操作 */ /** 修改按钮操作 */
handleUpdate(row) { handleUpdate(row) {
@@ -560,3 +649,12 @@ export default {
} }
}; };
</script> </script>
<style scoped>
.work-place-error {
color: #f56c6c;
font-size: 12px;
line-height: 1.5;
margin-top: 4px;
}
</style>

View File

@@ -107,8 +107,7 @@
<el-form-item label="工作地点" prop="workPlace"> <el-form-item label="工作地点" prop="workPlace">
<el-input <el-input
v-model="form.workPlace" v-model="form.workPlace"
readonly :placeholder="workPlaceLoading ? '正在获取定位…' : '请输入工作地点或点击「重新获取定位」'"
:placeholder="workPlaceLoading ? '正在获取定位…' : '请点击「重新获取定位」获取工作地点 (不可手动输入)'"
> >
<el-button <el-button
slot="append" slot="append"