|
|
@@ -1,253 +1,360 @@
|
|
|
<script setup>
|
|
|
- import { ref, computed, watch, nextTick, reactive } from 'vue';
|
|
|
- import { onLoad } from '@dcloudio/uni-app';
|
|
|
- import { getRuiYingReportDetail } from '@/api/ruiying';
|
|
|
- import { useDataDictStore } from '@/store/modules/dataDict';
|
|
|
-
|
|
|
- const props = defineProps({
|
|
|
- type: {
|
|
|
- type: String,
|
|
|
- default: 'edit',
|
|
|
- },
|
|
|
- });
|
|
|
-
|
|
|
- const NON_PROD_FIELDS = [
|
|
|
- { key: 'repairTime', label: '设备故障' },
|
|
|
- { key: 'selfStopTime', label: '设备保养' },
|
|
|
- { key: 'accidentTime', label: '工程质量' },
|
|
|
- { key: 'complexityTime', label: '技术受限' },
|
|
|
- { key: 'rectificationTime', label: '生产组织' },
|
|
|
- { key: 'waitingStopTime', label: '不可抗力' },
|
|
|
- { key: 'partyaDesign', label: '甲方设计' },
|
|
|
- { key: 'partyaPrepare', label: '甲方准备' },
|
|
|
- { key: 'partyaResource', label: '甲方资源' },
|
|
|
- { key: 'relocationTime', label: '生产配合' },
|
|
|
- { key: 'winterBreakTime', label: '待命' },
|
|
|
- { key: 'otherNptTime', label: '其他非生产时间' },
|
|
|
- ];
|
|
|
-
|
|
|
- const FORM_KEYS = [
|
|
|
- 'id',
|
|
|
- 'deptId',
|
|
|
- 'projectId',
|
|
|
- 'taskId',
|
|
|
- 'deptName',
|
|
|
- 'contractName',
|
|
|
- 'taskName',
|
|
|
- 'repairStatus',
|
|
|
- 'technique',
|
|
|
- 'wellCategory',
|
|
|
- 'designWellDepth',
|
|
|
- 'wellControlLevel',
|
|
|
- 'casingPipeSize',
|
|
|
- 'dailyFuel',
|
|
|
- 'currentOperation',
|
|
|
- 'nextPlan',
|
|
|
- 'ratedProductionTime',
|
|
|
- 'productionTime',
|
|
|
- 'totalStaffNum',
|
|
|
- 'onDutyStaffNum',
|
|
|
- 'leaveStaffNum',
|
|
|
- 'productionStatus',
|
|
|
- 'remark',
|
|
|
- 'createTime',
|
|
|
- 'opinion',
|
|
|
- 'repairTime',
|
|
|
- 'selfStopTime',
|
|
|
- 'accidentTime',
|
|
|
- 'complexityTime',
|
|
|
- 'rectificationTime',
|
|
|
- 'waitingStopTime',
|
|
|
- 'partyaDesign',
|
|
|
- 'partyaPrepare',
|
|
|
- 'partyaResource',
|
|
|
- 'relocationTime',
|
|
|
- 'winterBreakTime',
|
|
|
- 'otherNptTime',
|
|
|
- 'otherNptReason',
|
|
|
- 'status',
|
|
|
- 'auditStatus',
|
|
|
- ];
|
|
|
-
|
|
|
- const formType = ref('edit');
|
|
|
-
|
|
|
- const initFormData = () => {
|
|
|
- const base = {
|
|
|
- ratedProductionTime: 0,
|
|
|
- productionTime: 0,
|
|
|
- };
|
|
|
- // 初始化所有非生产时间字段为 0
|
|
|
- NON_PROD_FIELDS.forEach(field => {
|
|
|
- base[field.key] = 0;
|
|
|
- });
|
|
|
- return base;
|
|
|
+import { ref, computed, watch, nextTick, reactive } from "vue";
|
|
|
+import { onLoad } from "@dcloudio/uni-app";
|
|
|
+import { getRuiYingReportDetail } from "@/api/ruiying";
|
|
|
+import { useDataDictStore } from "@/store/modules/dataDict";
|
|
|
+import dayjs from "dayjs";
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ type: {
|
|
|
+ type: String,
|
|
|
+ default: "edit",
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+const NON_PROD_FIELDS = [
|
|
|
+ { key: "repairTime", label: "设备故障" },
|
|
|
+ { key: "selfStopTime", label: "设备保养" },
|
|
|
+ { key: "accidentTime", label: "工程质量" },
|
|
|
+ { key: "complexityTime", label: "技术受限" },
|
|
|
+ { key: "rectificationTime", label: "生产组织" },
|
|
|
+ { key: "waitingStopTime", label: "不可抗力" },
|
|
|
+ { key: "partyaDesign", label: "甲方设计" },
|
|
|
+ { key: "partyaPrepare", label: "甲方准备" },
|
|
|
+ { key: "partyaResource", label: "甲方资源" },
|
|
|
+ { key: "relocationTime", label: "生产配合" },
|
|
|
+ { key: "winterBreakTime", label: "待命" },
|
|
|
+ { key: "otherNptTime", label: "其他非生产时间" },
|
|
|
+];
|
|
|
+
|
|
|
+const FORM_KEYS = [
|
|
|
+ "id",
|
|
|
+ "deptId",
|
|
|
+ "projectId",
|
|
|
+ "taskId",
|
|
|
+ "deptName",
|
|
|
+ "contractName",
|
|
|
+ "taskName",
|
|
|
+ "repairStatus",
|
|
|
+ "technique",
|
|
|
+ "wellCategory",
|
|
|
+ "designWellDepth",
|
|
|
+ "wellControlLevel",
|
|
|
+ "casingPipeSize",
|
|
|
+ "dailyFuel",
|
|
|
+ "currentOperation",
|
|
|
+ "nextPlan",
|
|
|
+ "ratedProductionTime",
|
|
|
+ "productionTime",
|
|
|
+ "totalStaffNum",
|
|
|
+ "onDutyStaffNum",
|
|
|
+ "leaveStaffNum",
|
|
|
+ "reportDetails",
|
|
|
+ "constructionBrief",
|
|
|
+ "remark",
|
|
|
+ "createTime",
|
|
|
+ "opinion",
|
|
|
+ "repairTime",
|
|
|
+ "selfStopTime",
|
|
|
+ "accidentTime",
|
|
|
+ "complexityTime",
|
|
|
+ "rectificationTime",
|
|
|
+ "waitingStopTime",
|
|
|
+ "partyaDesign",
|
|
|
+ "partyaPrepare",
|
|
|
+ "partyaResource",
|
|
|
+ "relocationTime",
|
|
|
+ "winterBreakTime",
|
|
|
+ "otherNptTime",
|
|
|
+ "otherNptReason",
|
|
|
+ "status",
|
|
|
+ "auditStatus",
|
|
|
+];
|
|
|
+
|
|
|
+const formType = ref("edit");
|
|
|
+
|
|
|
+const initFormData = () => {
|
|
|
+ const base = {
|
|
|
+ ratedProductionTime: 0,
|
|
|
+ productionTime: 0,
|
|
|
+ constructionBrief: "",
|
|
|
+ reportDetails: [],
|
|
|
};
|
|
|
+ // 初始化所有非生产时间字段为 0
|
|
|
+ NON_PROD_FIELDS.forEach(field => {
|
|
|
+ base[field.key] = 0;
|
|
|
+ });
|
|
|
+ return base;
|
|
|
+};
|
|
|
|
|
|
- const form = ref(initFormData());
|
|
|
+const form = ref(initFormData());
|
|
|
|
|
|
- async function loadDetail(id) {
|
|
|
- try {
|
|
|
- const { data } = await getRuiYingReportDetail({ id });
|
|
|
+const formatT = arr =>
|
|
|
+ `${arr[0].toString().padStart(2, "0")}:${arr[1].toString().padStart(2, "0")}`;
|
|
|
|
|
|
- form.value = initFormData();
|
|
|
+async function loadDetail(id) {
|
|
|
+ try {
|
|
|
+ const { data } = await getRuiYingReportDetail({ id });
|
|
|
|
|
|
- FORM_KEYS.forEach(key => {
|
|
|
- if (Object.prototype.hasOwnProperty.call(data, key) && data[key] !== null && data[key] !== undefined) {
|
|
|
- form.value[key] = data[key];
|
|
|
- }
|
|
|
- });
|
|
|
- form.value.id = id;
|
|
|
+ form.value = initFormData();
|
|
|
|
|
|
- if (props.type.includes('approval') && data.auditStatus !== 10) {
|
|
|
- formType.value = 'readonly';
|
|
|
+ FORM_KEYS.forEach(key => {
|
|
|
+ if (
|
|
|
+ Object.prototype.hasOwnProperty.call(data, key) &&
|
|
|
+ data[key] !== null &&
|
|
|
+ data[key] !== undefined
|
|
|
+ ) {
|
|
|
+ form.value[key] = data[key];
|
|
|
}
|
|
|
+ });
|
|
|
|
|
|
- if (props.type.includes('edit') && data.status !== 0) {
|
|
|
- formType.value = 'readonly';
|
|
|
- }
|
|
|
+ form.value.reportDetails = form.value.reportDetails.map(item => ({
|
|
|
+ duration: item.duration || 0,
|
|
|
+ constructionDetail: item.constructionDetail || "",
|
|
|
+ currentOperation: item.currentOperation || "",
|
|
|
+ startTime: formatT(item.startTime),
|
|
|
+ endTime: formatT(item.endTime),
|
|
|
+ }));
|
|
|
|
|
|
- if (props.type.includes('detail')) {
|
|
|
- formType.value = 'readonly';
|
|
|
- }
|
|
|
- } finally {
|
|
|
+ if (!form.value.reportDetails.length) {
|
|
|
+ addReportDetailRow();
|
|
|
+ }
|
|
|
+
|
|
|
+ form.value.id = id;
|
|
|
+
|
|
|
+ if (props.type.includes("approval") && data.auditStatus !== 10) {
|
|
|
+ formType.value = "readonly";
|
|
|
+ }
|
|
|
+
|
|
|
+ if (props.type.includes("edit") && data.status !== 0) {
|
|
|
+ formType.value = "readonly";
|
|
|
+ }
|
|
|
+
|
|
|
+ if (props.type.includes("detail")) {
|
|
|
+ formType.value = "readonly";
|
|
|
}
|
|
|
+ } finally {
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- const dictStore = useDataDictStore();
|
|
|
+const addReportDetailRow = () => {
|
|
|
+ if (!form.value.reportDetails) {
|
|
|
+ form.value.reportDetails = [];
|
|
|
+ }
|
|
|
+ form.value.reportDetails.push({
|
|
|
+ startTime: "08:00",
|
|
|
+ endTime: "08:00",
|
|
|
+ duration: 0,
|
|
|
+ constructionDetail: "",
|
|
|
+ currentOperation: "",
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const removeReportDetailRow = index => {
|
|
|
+ if (index === 0) {
|
|
|
+ uni.showToast({ title: "至少填写一条生产动态", icon: "none" });
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- const nptReasonOptions = ref([]);
|
|
|
- const rigStatusOptions = ref([]);
|
|
|
- const techniqueOptions = ref([]);
|
|
|
+ form.value.reportDetails?.splice(index, 1);
|
|
|
+};
|
|
|
|
|
|
- const loadOptions = () => {
|
|
|
- nptReasonOptions.value = dictStore.getStrDictOptions('ryNptReason').map(v => ({
|
|
|
+const dictStore = useDataDictStore();
|
|
|
+
|
|
|
+const nptReasonOptions = ref([]);
|
|
|
+const rigStatusOptions = ref([]);
|
|
|
+const techniqueOptions = ref([]);
|
|
|
+
|
|
|
+const loadOptions = () => {
|
|
|
+ nptReasonOptions.value = dictStore
|
|
|
+ .getStrDictOptions("ryNptReason")
|
|
|
+ .map(v => ({
|
|
|
text: v.label,
|
|
|
value: v.value,
|
|
|
}));
|
|
|
- rigStatusOptions.value = dictStore.getStrDictOptions('repairStatus').map(v => ({
|
|
|
+ rigStatusOptions.value = dictStore
|
|
|
+ .getStrDictOptions("repairStatus")
|
|
|
+ .map(v => ({
|
|
|
text: v.label,
|
|
|
value: v.value,
|
|
|
}));
|
|
|
- techniqueOptions.value = dictStore.getStrDictOptions('rq_iot_project_technology_ry').map(v => ({
|
|
|
+ techniqueOptions.value = dictStore
|
|
|
+ .getStrDictOptions("rq_iot_project_technology_ry")
|
|
|
+ .map(v => ({
|
|
|
text: v.label,
|
|
|
value: v.value,
|
|
|
}));
|
|
|
- };
|
|
|
+};
|
|
|
|
|
|
- onLoad(options => {
|
|
|
- if (dictStore.dataDict.length <= 0) {
|
|
|
- dictStore.loadDataDictList().then(() => {
|
|
|
- loadOptions();
|
|
|
- });
|
|
|
- } else loadOptions();
|
|
|
- loadDetail(options.id);
|
|
|
+onLoad(options => {
|
|
|
+ if (dictStore.dataDict.length <= 0) {
|
|
|
+ dictStore.loadDataDictList().then(() => {
|
|
|
+ loadOptions();
|
|
|
+ });
|
|
|
+ } else loadOptions();
|
|
|
+ loadDetail(options.id);
|
|
|
+});
|
|
|
+
|
|
|
+const defaultProps = computed(() => ({
|
|
|
+ inputBorder: false,
|
|
|
+ clearable: false,
|
|
|
+ placeholder: "请输入",
|
|
|
+ style: {
|
|
|
+ "text-align": "right",
|
|
|
+ },
|
|
|
+ styles: {
|
|
|
+ disableColor: "#fff",
|
|
|
+ },
|
|
|
+}));
|
|
|
+
|
|
|
+const disabled = computed(() => field => {
|
|
|
+ if (field === "edit")
|
|
|
+ return (
|
|
|
+ formType.value === "readonly" ||
|
|
|
+ props.type.includes("approval") ||
|
|
|
+ props.type.includes("detail")
|
|
|
+ );
|
|
|
+ else return formType.value === "readonly";
|
|
|
+});
|
|
|
+
|
|
|
+const transitTime = computed(() => {
|
|
|
+ const cap = form.value.productionTime ?? 0;
|
|
|
+ const gas = form.value.ratedProductionTime ?? 0;
|
|
|
+
|
|
|
+ if (!gas) return { original: 0, value: "0%" };
|
|
|
+
|
|
|
+ const original = cap / gas;
|
|
|
+ return { original, value: (original * 100).toFixed(2) + "%" };
|
|
|
+});
|
|
|
+
|
|
|
+const formRef = ref(null);
|
|
|
+
|
|
|
+const onDutyStaffNum = computed(() => {
|
|
|
+ return (form.value.totalStaffNum ?? 0) - (form.value.leaveStaffNum ?? 0);
|
|
|
+});
|
|
|
+
|
|
|
+// 辅助函数:计算总时间
|
|
|
+const sumNonProdTimes = () => {
|
|
|
+ let sum = 0;
|
|
|
+ NON_PROD_FIELDS.forEach(field => {
|
|
|
+ sum += Number(form.value[field.key] || 0);
|
|
|
});
|
|
|
+ return sum;
|
|
|
+};
|
|
|
|
|
|
- const defaultProps = computed(() => ({
|
|
|
- inputBorder: false,
|
|
|
- clearable: false,
|
|
|
- placeholder: '请输入',
|
|
|
- style: {
|
|
|
- 'text-align': 'right',
|
|
|
- },
|
|
|
- styles: {
|
|
|
- disableColor: '#fff',
|
|
|
- },
|
|
|
- }));
|
|
|
-
|
|
|
- const disabled = computed(() => field => {
|
|
|
- if (field === 'edit')
|
|
|
- return formType.value === 'readonly' || props.type.includes('approval') || props.type.includes('detail');
|
|
|
- else return formType.value === 'readonly';
|
|
|
- });
|
|
|
+// 校验函数:总时间必须为 24
|
|
|
+const validateTotalTime = (rule, value, data, callback) => {
|
|
|
+ const rateTime = Number(form.value.ratedProductionTime || 0);
|
|
|
+ const time = Number(form.value.productionTime || 0);
|
|
|
|
|
|
- const transitTime = computed(() => {
|
|
|
- const cap = form.value.productionTime ?? 0;
|
|
|
- const gas = form.value.ratedProductionTime ?? 0;
|
|
|
+ const nonProdSum = sumNonProdTimes();
|
|
|
|
|
|
- if (!gas) return { original: 0, value: '0%' };
|
|
|
+ let total = 0;
|
|
|
+ let msg = "";
|
|
|
|
|
|
- const original = cap / gas;
|
|
|
- return { original, value: (original * 100).toFixed(2) + '%' };
|
|
|
- });
|
|
|
+ total = parseFloat((time + nonProdSum).toFixed(2));
|
|
|
+ msg = `生产(${time})+非生产(${nonProdSum})=${total}H,必须等于额定${rateTime}H`;
|
|
|
|
|
|
- const formRef = ref(null);
|
|
|
+ if (Math.abs(total - rateTime) > 0.01) {
|
|
|
+ callback(msg);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+};
|
|
|
+
|
|
|
+const rules = reactive({
|
|
|
+ repairStatus: {
|
|
|
+ rules: [{ required: true, errorMessage: "请输入施工状态" }],
|
|
|
+ },
|
|
|
+
|
|
|
+ ratedProductionTime: {
|
|
|
+ rules: [
|
|
|
+ { required: true, errorMessage: "请输入额定生产时间" },
|
|
|
+ { validateFunction: validateTotalTime },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ productionTime: {
|
|
|
+ rules: [
|
|
|
+ { required: true, errorMessage: "请输入生产时间" },
|
|
|
+ { validateFunction: validateTotalTime },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ constructionBrief: {
|
|
|
+ rules: [{ required: true, errorMessage: `请输入当日施工简报` }],
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+const allTimeKeys = [
|
|
|
+ "ratedProductionTime",
|
|
|
+ "productionTime",
|
|
|
+ ...NON_PROD_FIELDS.map(f => f.key),
|
|
|
+];
|
|
|
+
|
|
|
+watch(
|
|
|
+ () => allTimeKeys.map(key => form.value[key]),
|
|
|
+ () => {
|
|
|
+ nextTick(() => {
|
|
|
+ formRef.value?.validateField(["ratedProductionTime", "productionTime"]);
|
|
|
+ });
|
|
|
+ }
|
|
|
+);
|
|
|
|
|
|
- const onDutyStaffNum = computed(() => {
|
|
|
- return (form.value.totalStaffNum ?? 0) - (form.value.leaveStaffNum ?? 0);
|
|
|
- });
|
|
|
+defineExpose({ formRef, form, loadDetail });
|
|
|
|
|
|
- // 辅助函数:计算总时间
|
|
|
- const sumNonProdTimes = () => {
|
|
|
- let sum = 0;
|
|
|
- NON_PROD_FIELDS.forEach(field => {
|
|
|
- sum += Number(form.value[field.key] || 0);
|
|
|
- });
|
|
|
- return sum;
|
|
|
- };
|
|
|
+const orange = computed(() => {
|
|
|
+ const rateTime = Number(form.value.ratedProductionTime || 0);
|
|
|
+ const time = Number(form.value.productionTime || 0);
|
|
|
|
|
|
- // 校验函数:总时间必须为 24
|
|
|
- const validateTotalTime = (rule, value, data, callback) => {
|
|
|
- const rateTime = Number(form.value.ratedProductionTime || 0);
|
|
|
- const time = Number(form.value.productionTime || 0);
|
|
|
+ const nonProdSum = sumNonProdTimes();
|
|
|
|
|
|
- const nonProdSum = sumNonProdTimes();
|
|
|
+ let total = 0;
|
|
|
+ let msg = "";
|
|
|
|
|
|
- let total = 0;
|
|
|
- let msg = '';
|
|
|
+ total = parseFloat((time + nonProdSum).toFixed(2));
|
|
|
+ msg = `生产(${time})+非生产(${nonProdSum})=${total}H,必须等于额定${rateTime}H`;
|
|
|
|
|
|
- total = parseFloat((time + nonProdSum).toFixed(2));
|
|
|
- msg = `生产(${time})+非生产(${nonProdSum})=${total}H,必须等于额定${rateTime}H`;
|
|
|
+ if (Math.abs(total - rateTime) > 0.01) return true;
|
|
|
+ return false;
|
|
|
+});
|
|
|
|
|
|
- if (Math.abs(total - rateTime) > 0.01) {
|
|
|
- callback(msg);
|
|
|
- }
|
|
|
- return true;
|
|
|
- };
|
|
|
+const reportDetailsTimeRangeRef = ref(null);
|
|
|
|
|
|
- const rules = reactive({
|
|
|
- repairStatus: {
|
|
|
- rules: [{ required: true, errorMessage: '请输入施工状态' }],
|
|
|
- },
|
|
|
- productionStatus: {
|
|
|
- rules: [{ required: true, errorMessage: '请输入生产动态' }],
|
|
|
- },
|
|
|
- ratedProductionTime: {
|
|
|
- rules: [{ required: true, errorMessage: '请输入额定生产时间' }, { validateFunction: validateTotalTime }],
|
|
|
- },
|
|
|
- productionTime: {
|
|
|
- rules: [{ required: true, errorMessage: '请输入生产时间' }, { validateFunction: validateTotalTime }],
|
|
|
- },
|
|
|
- });
|
|
|
+const startTime = ref("00:00");
|
|
|
+const startDefaultTime = ref("08:00");
|
|
|
+const endTime = ref("24:00");
|
|
|
+const endDefaultTime = ref("08:00");
|
|
|
|
|
|
- const allTimeKeys = ['ratedProductionTime', 'productionTime', ...NON_PROD_FIELDS.map(f => f.key)];
|
|
|
+const reportDetailIndex = ref(0);
|
|
|
|
|
|
- watch(
|
|
|
- () => allTimeKeys.map(key => form.value[key]),
|
|
|
- () => {
|
|
|
- nextTick(() => {
|
|
|
- formRef.value?.validateField(['ratedProductionTime', 'productionTime']);
|
|
|
- });
|
|
|
- }
|
|
|
- );
|
|
|
+const handleClickTimeRangeItem = index => {
|
|
|
+ reportDetailIndex.value = index;
|
|
|
+ reportDetailsTimeRangeRef.value.open();
|
|
|
+};
|
|
|
|
|
|
- defineExpose({ formRef, form, loadDetail });
|
|
|
+const calculateDuration = row => {
|
|
|
+ if (!row.startTime || !row.endTime) {
|
|
|
+ row.duration = 0;
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- const orange = computed(() => {
|
|
|
- const rateTime = Number(form.value.ratedProductionTime || 0);
|
|
|
- const time = Number(form.value.productionTime || 0);
|
|
|
+ const todayStr = dayjs().format("YYYY-MM-DD");
|
|
|
+ const start = dayjs(`${todayStr} ${row.startTime}`);
|
|
|
+ const end = dayjs(`${todayStr} ${row.endTime}`);
|
|
|
|
|
|
- const nonProdSum = sumNonProdTimes();
|
|
|
+ let diffMinutes = end.diff(start, "minute");
|
|
|
|
|
|
- let total = 0;
|
|
|
- let msg = '';
|
|
|
+ if (diffMinutes < 0) {
|
|
|
+ diffMinutes += 1440;
|
|
|
+ }
|
|
|
|
|
|
- total = parseFloat((time + nonProdSum).toFixed(2));
|
|
|
- msg = `生产(${time})+非生产(${nonProdSum})=${total}H,必须等于额定${rateTime}H`;
|
|
|
+ row.duration = Number((diffMinutes / 60).toFixed(2));
|
|
|
+};
|
|
|
|
|
|
- if (Math.abs(total - rateTime) > 0.01) return true;
|
|
|
- return false;
|
|
|
- });
|
|
|
+const reportDetailsTimeRange = data => {
|
|
|
+ form.value.reportDetails[reportDetailIndex.value].startTime = data[0];
|
|
|
+ form.value.reportDetails[reportDetailIndex.value].endTime = data[1];
|
|
|
+
|
|
|
+ calculateDuration(form.value.reportDetails[reportDetailIndex.value]);
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
@@ -316,16 +423,28 @@
|
|
|
v-model="form.technique" />
|
|
|
</uni-forms-item>
|
|
|
<uni-forms-item label="井别" name="wellCategory">
|
|
|
- <uni-easyinput v-bind="defaultProps" v-model="form.wellCategory" :disabled="disabled('edit')" />
|
|
|
+ <uni-easyinput
|
|
|
+ v-bind="defaultProps"
|
|
|
+ v-model="form.wellCategory"
|
|
|
+ :disabled="disabled('edit')" />
|
|
|
</uni-forms-item>
|
|
|
<uni-forms-item label="设计井深(m)" name="designWellDepth">
|
|
|
- <uni-easyinput v-bind="defaultProps" v-model="form.designWellDepth" :disabled="disabled('edit')" />
|
|
|
+ <uni-easyinput
|
|
|
+ v-bind="defaultProps"
|
|
|
+ v-model="form.designWellDepth"
|
|
|
+ :disabled="disabled('edit')" />
|
|
|
</uni-forms-item>
|
|
|
<uni-forms-item label="井控级别" name="wellControlLevel">
|
|
|
- <uni-easyinput v-bind="defaultProps" v-model="form.wellControlLevel" :disabled="disabled('edit')" />
|
|
|
+ <uni-easyinput
|
|
|
+ v-bind="defaultProps"
|
|
|
+ v-model="form.wellControlLevel"
|
|
|
+ :disabled="disabled('edit')" />
|
|
|
</uni-forms-item>
|
|
|
<uni-forms-item label="套生段产管尺寸(mm)" name="casingPipeSize">
|
|
|
- <uni-easyinput v-bind="defaultProps" v-model="form.casingPipeSize" :disabled="disabled('edit')" />
|
|
|
+ <uni-easyinput
|
|
|
+ v-bind="defaultProps"
|
|
|
+ v-model="form.casingPipeSize"
|
|
|
+ :disabled="disabled('edit')" />
|
|
|
</uni-forms-item>
|
|
|
<uni-forms-item label="当日油耗(升)" name="dailyFuel">
|
|
|
<uni-easyinput
|
|
|
@@ -354,18 +473,34 @@
|
|
|
:maxlength="1000" />
|
|
|
</uni-forms-item>
|
|
|
<uni-forms-item label="运行时效" name="transitTime">
|
|
|
- <span class="readOnly" :class="{ 'red-text': transitTime.original > 1.0 }">{{ transitTime.value }}</span>
|
|
|
+ <span
|
|
|
+ class="readOnly"
|
|
|
+ :class="{ 'red-text': transitTime.original > 1.0 }"
|
|
|
+ >{{ transitTime.value }}</span
|
|
|
+ >
|
|
|
</uni-forms-item>
|
|
|
<uni-forms-item label="全员数量" name="totalStaffNum">
|
|
|
- <uni-easyinput type="number" v-bind="defaultProps" :disabled="disabled('edit')" v-model="form.totalStaffNum" />
|
|
|
+ <uni-easyinput
|
|
|
+ type="number"
|
|
|
+ v-bind="defaultProps"
|
|
|
+ :disabled="disabled('edit')"
|
|
|
+ v-model="form.totalStaffNum" />
|
|
|
</uni-forms-item>
|
|
|
<uni-forms-item label="在岗人数" name="onDutyStaffNum">
|
|
|
- <uni-easyinput type="number" v-bind="defaultProps" disabled v-model="onDutyStaffNum" />
|
|
|
+ <uni-easyinput
|
|
|
+ type="number"
|
|
|
+ v-bind="defaultProps"
|
|
|
+ disabled
|
|
|
+ v-model="onDutyStaffNum" />
|
|
|
</uni-forms-item>
|
|
|
<uni-forms-item label="休假人员数量" name="leaveStaffNum">
|
|
|
- <uni-easyinput type="number" v-bind="defaultProps" :disabled="disabled('edit')" v-model="form.leaveStaffNum" />
|
|
|
+ <uni-easyinput
|
|
|
+ type="number"
|
|
|
+ v-bind="defaultProps"
|
|
|
+ :disabled="disabled('edit')"
|
|
|
+ v-model="form.leaveStaffNum" />
|
|
|
</uni-forms-item>
|
|
|
- <uni-forms-item label="生产动态" name="productionStatus" required>
|
|
|
+ <!-- <uni-forms-item label="生产动态" name="productionStatus" required>
|
|
|
<uni-easyinput
|
|
|
type="textarea"
|
|
|
autoHeight
|
|
|
@@ -373,6 +508,19 @@
|
|
|
v-model="form.productionStatus"
|
|
|
:disabled="disabled('edit')"
|
|
|
:maxlength="1000" />
|
|
|
+ </uni-forms-item> -->
|
|
|
+ <uni-forms-item
|
|
|
+ v-if="props.type === 'approval' || props.type === 'approval-detail'"
|
|
|
+ label="当日施工简报"
|
|
|
+ required
|
|
|
+ name="constructionBrief">
|
|
|
+ <uni-easyinput
|
|
|
+ type="textarea"
|
|
|
+ autoHeight
|
|
|
+ v-bind="defaultProps"
|
|
|
+ :disabled="disabled('approval')"
|
|
|
+ v-model="form.constructionBrief"
|
|
|
+ :maxlength="2000" />
|
|
|
</uni-forms-item>
|
|
|
<uni-forms-item label="备注" name="remark">
|
|
|
<uni-easyinput
|
|
|
@@ -384,7 +532,10 @@
|
|
|
:maxlength="1000" />
|
|
|
</uni-forms-item>
|
|
|
<uv-divider text="生产时间" textPosition="left"></uv-divider>
|
|
|
- <uni-forms-item label="额定生产时间(H)" name="ratedProductionTime" required>
|
|
|
+ <uni-forms-item
|
|
|
+ label="额定生产时间(H)"
|
|
|
+ name="ratedProductionTime"
|
|
|
+ required>
|
|
|
<uni-easyinput
|
|
|
type="number"
|
|
|
v-bind="defaultProps"
|
|
|
@@ -401,8 +552,91 @@
|
|
|
v-model="form.productionTime" />
|
|
|
</uni-forms-item>
|
|
|
|
|
|
+ <uv-divider text="生产动态" textPosition="left"></uv-divider>
|
|
|
+ <uni-forms-item v-if="!disabled('edit')">
|
|
|
+ <button
|
|
|
+ type="primary"
|
|
|
+ size="mini"
|
|
|
+ class="detail-btn"
|
|
|
+ @click="addReportDetailRow()">
|
|
|
+ 添加一行
|
|
|
+ </button>
|
|
|
+ </uni-forms-item>
|
|
|
+ <template v-for="(item, index) in form.reportDetails" :key="index">
|
|
|
+ <uni-forms-item label="日期" style="margin-top: 32px">
|
|
|
+ <span class="readOnly">{{
|
|
|
+ dayjs(form.createTime).format("YYYY-MM-DD")
|
|
|
+ }}</span>
|
|
|
+ </uni-forms-item>
|
|
|
+ <uni-forms-item :label="`${$t('ruiDu.timeNode')}:`" required>
|
|
|
+ <view
|
|
|
+ class="item-content"
|
|
|
+ @click="disabled('edit') ? '' : handleClickTimeRangeItem(index)">
|
|
|
+ <view class="time-range-item" v-if="item.startTime && item.endTime">
|
|
|
+ {{ item.startTime }} 至 {{ item.endTime }}
|
|
|
+ </view>
|
|
|
+ <view class="time-range-item" v-else>
|
|
|
+ {{ selectPlaceholder }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </uni-forms-item>
|
|
|
+ <uni-forms-item label="时长(H)">
|
|
|
+ <span class="readOnly">{{ item.duration }}</span>
|
|
|
+ </uni-forms-item>
|
|
|
+ <uni-forms-item
|
|
|
+ label="工况"
|
|
|
+ required
|
|
|
+ :name="['reportDetails', index, 'currentOperation']"
|
|
|
+ :rules="[{ required: true, errorMessage: '请输入工况' }]">
|
|
|
+ <uni-easyinput
|
|
|
+ type="textarea"
|
|
|
+ autoHeight
|
|
|
+ v-bind="defaultProps"
|
|
|
+ :disabled="disabled('edit')"
|
|
|
+ v-model="item.currentOperation"
|
|
|
+ :maxlength="2000" />
|
|
|
+ </uni-forms-item>
|
|
|
+ <!-- <uni-forms-item
|
|
|
+ label="结束井深(m)"
|
|
|
+ required
|
|
|
+ :name="['reportDetails', index, 'currentDepth']"
|
|
|
+ :rules="[{ required: true, errorMessage: '请输入结束深度' }, { validateFunction: validateLastCurrentDepth }]">
|
|
|
+ <uni-easyinput
|
|
|
+ type="number"
|
|
|
+ v-bind="defaultProps"
|
|
|
+ :disabled="disabled('edit')"
|
|
|
+ v-model.number="item.currentDepth" />
|
|
|
+ </uni-forms-item> -->
|
|
|
+ <uni-forms-item
|
|
|
+ label="详情"
|
|
|
+ required
|
|
|
+ :name="['reportDetails', index, 'constructionDetail']"
|
|
|
+ :rules="[{ required: true, errorMessage: '请输入详情' }]">
|
|
|
+ <uni-easyinput
|
|
|
+ type="textarea"
|
|
|
+ autoHeight
|
|
|
+ v-bind="defaultProps"
|
|
|
+ :disabled="disabled('edit')"
|
|
|
+ v-model="item.constructionDetail"
|
|
|
+ :maxlength="2000" />
|
|
|
+ </uni-forms-item>
|
|
|
+ <uni-forms-item v-if="!disabled('edit')" label="操作">
|
|
|
+ <button
|
|
|
+ type="warn"
|
|
|
+ size="mini"
|
|
|
+ class="detail-btn"
|
|
|
+ @click="removeReportDetailRow(index)">
|
|
|
+ 删除
|
|
|
+ </button>
|
|
|
+ </uni-forms-item>
|
|
|
+ </template>
|
|
|
+
|
|
|
<uv-divider text="非生产时间" textPosition="left"></uv-divider>
|
|
|
- <uni-forms-item v-for="field in NON_PROD_FIELDS" :key="field.key" :label="field.label + '(H)'" :name="field.key">
|
|
|
+ <uni-forms-item
|
|
|
+ v-for="field in NON_PROD_FIELDS"
|
|
|
+ :key="field.key"
|
|
|
+ :label="field.label + '(H)'"
|
|
|
+ :name="field.key">
|
|
|
<uni-easyinput
|
|
|
type="number"
|
|
|
:class="{ 'orange-text': orange }"
|
|
|
@@ -421,7 +655,10 @@
|
|
|
:maxlength="1000" />
|
|
|
</uni-forms-item>
|
|
|
|
|
|
- <uni-forms-item v-if="type.includes('approval')" label="审批意见" name="opinion">
|
|
|
+ <uni-forms-item
|
|
|
+ v-if="type.includes('approval')"
|
|
|
+ label="审批意见"
|
|
|
+ name="opinion">
|
|
|
<uni-easyinput
|
|
|
type="textarea"
|
|
|
autoHeight
|
|
|
@@ -432,164 +669,172 @@
|
|
|
</uni-forms-item>
|
|
|
</uni-forms>
|
|
|
</view>
|
|
|
+
|
|
|
+ <tpf-time-range
|
|
|
+ ref="reportDetailsTimeRangeRef"
|
|
|
+ :startTime="startTime"
|
|
|
+ :startDefaultTime="startDefaultTime"
|
|
|
+ :endTime="endTime"
|
|
|
+ :endDefaultTime="endDefaultTime"
|
|
|
+ @timeRange="reportDetailsTimeRange"></tpf-time-range>
|
|
|
</template>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
- .content {
|
|
|
- background-color: white;
|
|
|
- padding: 16px 16px;
|
|
|
- border-radius: 8px;
|
|
|
- box-sizing: border-box;
|
|
|
- }
|
|
|
-
|
|
|
- .uni-forms {
|
|
|
- margin-top: 10px;
|
|
|
+.content {
|
|
|
+ background-color: white;
|
|
|
+ padding: 16px 16px;
|
|
|
+ border-radius: 8px;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.uni-forms {
|
|
|
+ margin-top: 10px;
|
|
|
+ height: 100%;
|
|
|
+
|
|
|
+ .uni-form {
|
|
|
height: 100%;
|
|
|
+ }
|
|
|
|
|
|
- .uni-form {
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
-
|
|
|
- .uni-forms-item {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- flex: 1;
|
|
|
- margin-bottom: 6px;
|
|
|
- border-bottom: 1px dashed #cacccf;
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.uni-forms-item__content) {
|
|
|
- text-align: right;
|
|
|
- .readOnly {
|
|
|
- padding-right: 10px;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.uni-forms-item__label) {
|
|
|
- height: 44px;
|
|
|
- font-weight: 500;
|
|
|
- font-size: 14px;
|
|
|
- color: #333333 !important;
|
|
|
- width: max-content !important;
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.uni-select) {
|
|
|
- border: none;
|
|
|
- text-align: right;
|
|
|
- padding-right: 0;
|
|
|
- .uniui-bottom:before {
|
|
|
- content: '\e6b5' !important;
|
|
|
- font-size: 16px !important;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.uni-easyinput__content-textarea) {
|
|
|
- min-height: inherit;
|
|
|
- margin: 10px;
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.is-disabled) {
|
|
|
- color: #333333 !important;
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.red-text > .is-disabled) {
|
|
|
- color: rgb(220 38 38 / 0.8) !important;
|
|
|
- }
|
|
|
-
|
|
|
- :deep(.orange-text > .is-disabled) {
|
|
|
- color: rgb(234 88 12 / 0.8) !important;
|
|
|
- }
|
|
|
+ .uni-forms-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ flex: 1;
|
|
|
+ margin-bottom: 6px;
|
|
|
+ border-bottom: 1px dashed #cacccf;
|
|
|
+ }
|
|
|
|
|
|
- :deep(.uni-select--disabled) {
|
|
|
- background-color: #fff;
|
|
|
+ :deep(.uni-forms-item__content) {
|
|
|
+ text-align: right;
|
|
|
+ .readOnly {
|
|
|
+ padding-right: 10px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- .red-text {
|
|
|
- color: rgb(220 38 38 / 0.8) !important;
|
|
|
+ :deep(.uni-forms-item__label) {
|
|
|
+ height: 44px;
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #333333 !important;
|
|
|
+ width: max-content !important;
|
|
|
}
|
|
|
|
|
|
- .blue-text {
|
|
|
- color: rgb(59 130 246 / 0.8) !important;
|
|
|
+ :deep(.uni-select) {
|
|
|
+ border: none;
|
|
|
+ text-align: right;
|
|
|
+ padding-right: 0;
|
|
|
+ .uniui-bottom:before {
|
|
|
+ content: "\e6b5" !important;
|
|
|
+ font-size: 16px !important;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- .orange-text {
|
|
|
- color: rgb(234 88 12 / 0.8) !important;
|
|
|
+ :deep(.uni-easyinput__content-textarea) {
|
|
|
+ min-height: inherit;
|
|
|
+ margin: 10px;
|
|
|
}
|
|
|
|
|
|
- .red {
|
|
|
- border: 1px solid rgb(254 226 226);
|
|
|
- color: rgb(220 38 38 / 0.8);
|
|
|
- background-color: rgb(254 226 226);
|
|
|
+ :deep(.is-disabled) {
|
|
|
+ color: #333333 !important;
|
|
|
}
|
|
|
|
|
|
- .orange {
|
|
|
- border: 1px solid rgb(254 215 170);
|
|
|
- color: rgb(234 88 12 / 0.8);
|
|
|
- background-color: rgb(254 215 170);
|
|
|
+ :deep(.red-text > .is-disabled) {
|
|
|
+ color: rgb(220 38 38 / 0.8) !important;
|
|
|
}
|
|
|
|
|
|
- .blue {
|
|
|
- border: 1px solid rgb(219 234 254);
|
|
|
- color: rgb(59 130 246 / 0.8);
|
|
|
- background-color: rgb(240 249 255);
|
|
|
+ :deep(.orange-text > .is-disabled) {
|
|
|
+ color: rgb(234 88 12 / 0.8) !important;
|
|
|
}
|
|
|
|
|
|
- .tip {
|
|
|
- border-radius: 8px;
|
|
|
- border: 1px solid #e5e5e5;
|
|
|
- background-color: rgba(239, 246, 255, 0.8);
|
|
|
- box-sizing: border-box;
|
|
|
- padding: 10px;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- gap: 6px;
|
|
|
-
|
|
|
- .item {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
- font-size: 12px;
|
|
|
-
|
|
|
- .left {
|
|
|
- color: rgb(75 85 99);
|
|
|
-
|
|
|
- span {
|
|
|
- color: rgb(31 41 55);
|
|
|
- font-weight: 600;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .right {
|
|
|
- display: inline-flex;
|
|
|
- align-items: center;
|
|
|
- border-radius: 4px;
|
|
|
- padding: 2px 4px;
|
|
|
- font-weight: 500;
|
|
|
- }
|
|
|
- }
|
|
|
+ :deep(.uni-select--disabled) {
|
|
|
+ background-color: #fff;
|
|
|
}
|
|
|
-
|
|
|
- .opinion {
|
|
|
- border-radius: 8px;
|
|
|
- border: 1px solid rgb(254 240 138);
|
|
|
- background-color: rgb(254 252 232);
|
|
|
- box-sizing: border-box;
|
|
|
- padding: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.red-text {
|
|
|
+ color: rgb(220 38 38 / 0.8) !important;
|
|
|
+}
|
|
|
+
|
|
|
+.blue-text {
|
|
|
+ color: rgb(59 130 246 / 0.8) !important;
|
|
|
+}
|
|
|
+
|
|
|
+.orange-text {
|
|
|
+ color: rgb(234 88 12 / 0.8) !important;
|
|
|
+}
|
|
|
+
|
|
|
+.red {
|
|
|
+ border: 1px solid rgb(254 226 226);
|
|
|
+ color: rgb(220 38 38 / 0.8);
|
|
|
+ background-color: rgb(254 226 226);
|
|
|
+}
|
|
|
+
|
|
|
+.orange {
|
|
|
+ border: 1px solid rgb(254 215 170);
|
|
|
+ color: rgb(234 88 12 / 0.8);
|
|
|
+ background-color: rgb(254 215 170);
|
|
|
+}
|
|
|
+
|
|
|
+.blue {
|
|
|
+ border: 1px solid rgb(219 234 254);
|
|
|
+ color: rgb(59 130 246 / 0.8);
|
|
|
+ background-color: rgb(240 249 255);
|
|
|
+}
|
|
|
+
|
|
|
+.tip {
|
|
|
+ border-radius: 8px;
|
|
|
+ border: 1px solid #e5e5e5;
|
|
|
+ background-color: rgba(239, 246, 255, 0.8);
|
|
|
+ box-sizing: border-box;
|
|
|
+ padding: 10px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 6px;
|
|
|
+
|
|
|
+ .item {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: space-between;
|
|
|
font-size: 12px;
|
|
|
- margin-top: 10px;
|
|
|
|
|
|
.left {
|
|
|
- font-weight: 600;
|
|
|
- color: rgb(133 77 14);
|
|
|
+ color: rgb(75 85 99);
|
|
|
+
|
|
|
+ span {
|
|
|
+ color: rgb(31 41 55);
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.right {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ border-radius: 4px;
|
|
|
+ padding: 2px 4px;
|
|
|
font-weight: 500;
|
|
|
- color: rgb(75 85 99);
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+.opinion {
|
|
|
+ border-radius: 8px;
|
|
|
+ border: 1px solid rgb(254 240 138);
|
|
|
+ background-color: rgb(254 252 232);
|
|
|
+ box-sizing: border-box;
|
|
|
+ padding: 10px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ font-size: 12px;
|
|
|
+ margin-top: 10px;
|
|
|
+
|
|
|
+ .left {
|
|
|
+ font-weight: 600;
|
|
|
+ color: rgb(133 77 14);
|
|
|
+ }
|
|
|
+
|
|
|
+ .right {
|
|
|
+ font-weight: 500;
|
|
|
+ color: rgb(75 85 99);
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|