form.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888
  1. <script setup>
  2. import { ref, computed, watch, nextTick, reactive } from "vue";
  3. import { onLoad } from "@dcloudio/uni-app";
  4. import { getRuiYingReportDetail } from "@/api/ruiying";
  5. import { useDataDictStore } from "@/store/modules/dataDict";
  6. import tpfTimeRange from "@/components/tpf-time-range/tpf-time-range.vue";
  7. import dayjs from "dayjs";
  8. import { useDebounceFn } from "@/utils/useDebounceFn.js";
  9. const props = defineProps({
  10. type: {
  11. type: String,
  12. default: "edit",
  13. },
  14. });
  15. const NON_PROD_FIELDS = [
  16. { key: "repairTime", label: "设备故障" },
  17. { key: "selfStopTime", label: "设备保养" },
  18. { key: "accidentTime", label: "工程质量" },
  19. { key: "complexityTime", label: "技术受限" },
  20. { key: "rectificationTime", label: "生产组织" },
  21. { key: "waitingStopTime", label: "不可抗力" },
  22. { key: "partyaDesign", label: "甲方设计" },
  23. { key: "partyaPrepare", label: "甲方准备" },
  24. { key: "partyaResource", label: "甲方资源" },
  25. { key: "relocationTime", label: "生产配合" },
  26. { key: "winterBreakTime", label: "待命" },
  27. { key: "otherNptTime", label: "其他非生产时间" },
  28. ];
  29. const FORM_KEYS = [
  30. "id",
  31. "deptId",
  32. "projectId",
  33. "taskId",
  34. "deptName",
  35. "contractName",
  36. "taskName",
  37. "rigStatus",
  38. "designWellDepth",
  39. "currentDepth",
  40. "dailyPowerUsage",
  41. "dailyFuel",
  42. "mudDensity",
  43. "mudViscosity",
  44. "lateralLength",
  45. "wellInclination",
  46. "azimuth",
  47. "designWellStruct",
  48. "personnel",
  49. "drillingWorkingTime",
  50. "otherProductionTime",
  51. "lastCurrentDepth",
  52. "reportDetails",
  53. "constructionBrief",
  54. "remark",
  55. "createTime",
  56. "opinion",
  57. "repairTime",
  58. "selfStopTime",
  59. "accidentTime",
  60. "complexityTime",
  61. "rectificationTime",
  62. "waitingStopTime",
  63. "partyaDesign",
  64. "partyaPrepare",
  65. "partyaResource",
  66. "relocationTime",
  67. "winterBreakTime",
  68. "otherNptTime",
  69. "otherNptReason",
  70. "status",
  71. "auditStatus",
  72. ];
  73. const formType = ref("edit");
  74. const initFormData = () => {
  75. const base = {
  76. drillingWorkingTime: 0,
  77. otherProductionTime: 0,
  78. constructionBrief: "",
  79. reportDetails: [],
  80. };
  81. // 初始化所有非生产时间字段为 0
  82. NON_PROD_FIELDS.forEach(field => {
  83. base[field.key] = 0;
  84. });
  85. return base;
  86. };
  87. const form = ref(initFormData());
  88. const formatT = arr =>
  89. `${arr[0].toString().padStart(2, "0")}:${arr[1].toString().padStart(2, "0")}`;
  90. async function loadDetail(id) {
  91. try {
  92. const { data } = await getRuiYingReportDetail({ id });
  93. form.value = initFormData();
  94. FORM_KEYS.forEach(key => {
  95. if (
  96. Object.prototype.hasOwnProperty.call(data, key) &&
  97. data[key] !== null &&
  98. data[key] !== undefined
  99. ) {
  100. form.value[key] = data[key];
  101. }
  102. });
  103. form.value.reportDetails = form.value.reportDetails.map(item => ({
  104. reportDate: item.reportDate || form.value.createTime,
  105. duration: item.duration || 0,
  106. constructionDetail: item.constructionDetail || "",
  107. currentDepth: item.currentDepth || 0,
  108. currentOperation: item.currentOperation || "",
  109. startTime: formatT(item.startTime),
  110. endTime: formatT(item.endTime),
  111. }));
  112. if (!form.value.reportDetails.length) {
  113. addReportDetailRow();
  114. }
  115. form.value.id = id;
  116. if (props.type.includes("approval") && data.auditStatus !== 10) {
  117. formType.value = "readonly";
  118. }
  119. if (props.type.includes("edit") && data.status !== 0) {
  120. formType.value = "readonly";
  121. }
  122. if (props.type.includes("detail")) {
  123. formType.value = "readonly";
  124. }
  125. } finally {
  126. }
  127. }
  128. const addReportDetailRow = () => {
  129. if (!form.value.reportDetails) {
  130. form.value.reportDetails = [];
  131. }
  132. form.value.reportDetails.push({
  133. reportDate: form.value.createTime ?? dayjs().valueOf(),
  134. startTime: "08:00",
  135. endTime: "08:00",
  136. duration: 0,
  137. constructionDetail: "",
  138. currentDepth: 0,
  139. currentOperation: "",
  140. });
  141. };
  142. const removeReportDetailRow = index => {
  143. if (index === 0) {
  144. uni.showToast({ title: "至少填写一条生产动态", icon: "none" });
  145. return;
  146. }
  147. form.value.reportDetails?.splice(index, 1);
  148. };
  149. const dictStore = useDataDictStore();
  150. const nptReasonOptions = ref([]);
  151. const rigStatusOptions = ref([]);
  152. const loadOptions = () => {
  153. nptReasonOptions.value = dictStore.getStrDictOptions("nptReason").map(v => ({
  154. text: v.label,
  155. value: v.value,
  156. }));
  157. rigStatusOptions.value = dictStore.getStrDictOptions("rigStatus").map(v => ({
  158. text: v.label,
  159. value: v.value,
  160. }));
  161. };
  162. onLoad(options => {
  163. if (dictStore.dataDict.length <= 0) {
  164. dictStore.loadDataDictList().then(() => {
  165. loadOptions();
  166. });
  167. } else loadOptions();
  168. loadDetail(options.id);
  169. });
  170. const defaultProps = computed(() => ({
  171. inputBorder: false,
  172. clearable: false,
  173. placeholder: "请输入",
  174. style: {
  175. "text-align": "right",
  176. },
  177. styles: {
  178. disableColor: "#fff",
  179. },
  180. }));
  181. const disabled = computed(() => field => {
  182. if (field === "edit")
  183. return (
  184. formType.value === "readonly" ||
  185. props.type.includes("approval") ||
  186. props.type.includes("detail")
  187. );
  188. else return formType.value === "readonly";
  189. });
  190. const formRef = ref(null);
  191. // 辅助函数:计算总时间
  192. const sumNonProdTimes = () => {
  193. let sum = 0;
  194. NON_PROD_FIELDS.forEach(field => {
  195. sum += Number(form.value[field.key] || 0);
  196. });
  197. return sum;
  198. };
  199. // 校验函数:总时间必须为 24
  200. const validateTotalTime = (rule, value, data, callback) => {
  201. const drillingTime = Number(form.value.drillingWorkingTime || 0);
  202. const otherTime = Number(form.value.otherProductionTime || 0);
  203. const nonProdSum = sumNonProdTimes();
  204. let total = 0;
  205. let msg = "";
  206. total = parseFloat((drillingTime + otherTime + nonProdSum).toFixed(2));
  207. msg = `进尺(${drillingTime})+其他(${otherTime})+非生产(${nonProdSum})=${total}H,必须为24H`;
  208. if (Math.abs(total - 24) > 0.01) {
  209. callback(msg);
  210. }
  211. return true;
  212. };
  213. const validateLastCurrentDepth = (rule, value, data, callback) => {
  214. if (value && Number(value) < (form.value.lastCurrentDepth ?? 0)) {
  215. callback(`当前深度需大于等于上一次填报深度${form.value.lastCurrentDepth}m`);
  216. } else {
  217. callback();
  218. }
  219. };
  220. // uni-forms 规则定义
  221. const rules = reactive({
  222. currentDepth: {
  223. rules: [
  224. { required: true, errorMessage: "请输入当前深度" },
  225. { validateFunction: validateLastCurrentDepth },
  226. ],
  227. },
  228. drillingWorkingTime: {
  229. rules: [
  230. { required: true, errorMessage: "请输入进尺工作时间" },
  231. { validateFunction: validateTotalTime },
  232. ],
  233. },
  234. constructionBrief: {
  235. rules: [
  236. {
  237. required: props.type === "approval",
  238. errorMessage: `请输入当日施工简报`,
  239. },
  240. ],
  241. },
  242. });
  243. const allTimeKeys = [
  244. "drillingWorkingTime",
  245. "otherProductionTime",
  246. ...NON_PROD_FIELDS.map(f => f.key),
  247. ];
  248. watch(
  249. () => allTimeKeys.map(key => form.value[key]),
  250. () => {
  251. nextTick(() => {
  252. formRef.value?.validateField("drillingWorkingTime");
  253. });
  254. }
  255. );
  256. defineExpose({ formRef, form, loadDetail });
  257. const orange = computed(() => {
  258. const drillingTime = Number(form.value.drillingWorkingTime || 0);
  259. const otherTime = Number(form.value.otherProductionTime || 0);
  260. const nonProdSum = sumNonProdTimes();
  261. let total = 0;
  262. total = parseFloat((drillingTime + otherTime + nonProdSum).toFixed(2));
  263. if (Math.abs(total - 24) > 0.01) return true;
  264. return false;
  265. });
  266. const reportDetailsTimeRangeRef = ref(null);
  267. const startTime = ref("00:00");
  268. const startDefaultTime = ref("08:00");
  269. const endTime = ref("24:00");
  270. const endDefaultTime = ref("08:00");
  271. const reportDetailIndex = ref(0);
  272. const handleClickTimeRangeItem = index => {
  273. reportDetailIndex.value = index;
  274. reportDetailsTimeRangeRef.value.open();
  275. };
  276. const calculateDuration = row => {
  277. if (!row.startTime || !row.endTime) {
  278. row.duration = 0;
  279. return;
  280. }
  281. const todayStr = dayjs().format("YYYY-MM-DD");
  282. const start = dayjs(`${todayStr} ${row.startTime}`);
  283. const end = dayjs(`${todayStr} ${row.endTime}`);
  284. let diffMinutes = end.diff(start, "minute");
  285. if (diffMinutes < 0) {
  286. diffMinutes += 1440;
  287. }
  288. row.duration = Number((diffMinutes / 60).toFixed(2));
  289. };
  290. const reportDetailsTimeRange = data => {
  291. form.value.reportDetails[reportDetailIndex.value].startTime = data[0];
  292. form.value.reportDetails[reportDetailIndex.value].endTime = data[1];
  293. calculateDuration(form.value.reportDetails[reportDetailIndex.value]);
  294. inputCurrentDepth();
  295. };
  296. const inputCurrentDepth = useDebounceFn(function inputCurrentDepth() {
  297. const details = form.value.reportDetails;
  298. if (Array.isArray(details) && details.length > 0) {
  299. const latestDetail = details.reduce((prev, current) => {
  300. const currentFullTime = dayjs(current.reportDate)
  301. .hour(parseInt(current.endTime.split(":")[0]))
  302. .minute(parseInt(current.endTime.split(":")[1]))
  303. .valueOf();
  304. const prevFullTime = dayjs(prev.reportDate)
  305. .hour(parseInt(prev.endTime.split(":")[0]))
  306. .minute(parseInt(prev.endTime.split(":")[1]))
  307. .valueOf();
  308. return currentFullTime >= prevFullTime ? current : prev;
  309. });
  310. form.value.currentDepth = latestDetail.currentDepth;
  311. }
  312. }, 300);
  313. </script>
  314. <template>
  315. <view class="content">
  316. <view class="tip">
  317. <view class="item">
  318. <view class="left">
  319. <span>油量消耗:</span>
  320. 当日油耗
  321. </view>
  322. <span class="right red"> >9000升 红色预警 </span>
  323. </view>
  324. <view class="item">
  325. <view class="left">
  326. <span>时间平衡:</span>
  327. 进尺 + 其它生产 + 非生产 = 24H
  328. </view>
  329. <span class="right orange"> ≠24H 橙色预警 </span>
  330. </view>
  331. </view>
  332. <view v-if="!type.includes('approval') && form.opinion" class="opinion">
  333. <span class="left">审批意见:</span>
  334. <span class="right"> {{ form.opinion }} </span>
  335. </view>
  336. <uni-forms
  337. ref="formRef"
  338. labelWidth="auto"
  339. :model="form"
  340. :rules="rules"
  341. validateTrigger="submit"
  342. err-show-type="toast">
  343. <uni-forms-item label="施工队伍" name="deptName">
  344. <span class="readOnly">{{ form.deptName }}</span>
  345. </uni-forms-item>
  346. <uni-forms-item label="项目" name="contractName">
  347. <span class="readOnly">{{ form.contractName }}</span>
  348. </uni-forms-item>
  349. <uni-forms-item label="任务" name="taskName">
  350. <span class="readOnly">{{ form.taskName }}</span>
  351. </uni-forms-item>
  352. <uni-forms-item label="施工状态" name="rigStatus">
  353. <uni-data-select
  354. :clear="true"
  355. align="right"
  356. placeholder="请选择"
  357. :localdata="rigStatusOptions"
  358. placement="top"
  359. :disabled="disabled('edit')"
  360. v-model="form.rigStatus" />
  361. </uni-forms-item>
  362. <uni-forms-item label="设计井深(m)" name="designWellDepth">
  363. <span class="readOnly">{{ form.designWellDepth }}</span>
  364. </uni-forms-item>
  365. <uni-forms-item label="当前井深(m)" name="currentDepth" required>
  366. <uni-easyinput
  367. type="number"
  368. v-bind="defaultProps"
  369. :disabled="disabled('edit')"
  370. v-model="form.currentDepth" />
  371. </uni-forms-item>
  372. <uni-forms-item label="当日用电量(kWh)" name="dailyPowerUsage">
  373. <uni-easyinput
  374. type="number"
  375. v-bind="defaultProps"
  376. :disabled="disabled('edit')"
  377. v-model="form.dailyPowerUsage" />
  378. </uni-forms-item>
  379. <uni-forms-item label="当日油耗(升)" name="dailyFuel">
  380. <uni-easyinput
  381. type="number"
  382. :class="{ 'red-text': Number(form.dailyFuel) > 9000 }"
  383. v-bind="defaultProps"
  384. :disabled="disabled('edit')"
  385. v-model="form.dailyFuel" />
  386. </uni-forms-item>
  387. <uni-forms-item label="泥浆粘度(S)" name="mudViscosity">
  388. <uni-easyinput
  389. type="number"
  390. v-bind="defaultProps"
  391. :disabled="disabled('edit')"
  392. v-model="form.mudViscosity" />
  393. </uni-forms-item>
  394. <!-- <uni-forms-item label="泥浆粘度(S)" name="mudViscosity">
  395. <uni-easyinput
  396. type="number"
  397. v-bind="defaultProps"
  398. :disabled="disabled('edit')"
  399. v-model="form.mudViscosity" />
  400. </uni-forms-item> -->
  401. <uni-forms-item label="水平段长度(m)" name="lateralLength">
  402. <uni-easyinput
  403. type="number"
  404. v-bind="defaultProps"
  405. :disabled="disabled('edit')"
  406. v-model="form.lateralLength" />
  407. </uni-forms-item>
  408. <uni-forms-item label="井斜(°)" name="wellInclination">
  409. <uni-easyinput
  410. type="number"
  411. v-bind="defaultProps"
  412. :disabled="disabled('edit')"
  413. v-model="form.wellInclination" />
  414. </uni-forms-item>
  415. <uni-forms-item label="方位(°)" name="azimuth">
  416. <uni-easyinput
  417. type="number"
  418. v-bind="defaultProps"
  419. :disabled="disabled('edit')"
  420. v-model="form.azimuth" />
  421. </uni-forms-item>
  422. <uni-forms-item label="设计井身结构" name="designWellStruct">
  423. <uni-easyinput
  424. type="textarea"
  425. autoHeight
  426. v-bind="defaultProps"
  427. :disabled="disabled('edit')"
  428. v-model="form.designWellStruct"
  429. :maxlength="1000" />
  430. </uni-forms-item>
  431. <uni-forms-item label="人员情况" name="personnel">
  432. <uni-easyinput
  433. type="textarea"
  434. autoHeight
  435. v-bind="defaultProps"
  436. :disabled="disabled('edit')"
  437. v-model="form.personnel"
  438. :maxlength="1000" />
  439. </uni-forms-item>
  440. <!-- <uni-forms-item label="生产动态" name="productionStatus" required>
  441. <uni-easyinput
  442. type="textarea"
  443. autoHeight
  444. v-bind="defaultProps"
  445. v-model="form.productionStatus"
  446. :disabled="disabled('edit')"
  447. :maxlength="1000" />
  448. </uni-forms-item> -->
  449. <uni-forms-item
  450. label="当日施工简报"
  451. :required="type === 'approval'"
  452. name="constructionBrief">
  453. <uni-easyinput
  454. type="textarea"
  455. autoHeight
  456. v-bind="defaultProps"
  457. :disabled="type !== 'approval'"
  458. v-model="form.constructionBrief"
  459. :maxlength="2000" />
  460. </uni-forms-item>
  461. <uni-forms-item label="备注" name="remark">
  462. <uni-easyinput
  463. type="textarea"
  464. autoHeight
  465. v-bind="defaultProps"
  466. :disabled="disabled('edit')"
  467. v-model="form.remark"
  468. :maxlength="1000" />
  469. </uni-forms-item>
  470. <uv-divider text="生产动态" textPosition="left"></uv-divider>
  471. <uni-forms-item v-if="!disabled('edit')">
  472. <button
  473. type="primary"
  474. size="mini"
  475. class="detail-btn"
  476. @click="addReportDetailRow()">
  477. 添加一行
  478. </button>
  479. </uni-forms-item>
  480. <template v-for="(item, index) in form.reportDetails" :key="index">
  481. <uv-divider v-if="index !== 0" class="divider"></uv-divider>
  482. <uni-forms-item
  483. label="日期"
  484. required
  485. :name="['reportDetails', index, 'reportDate']"
  486. :rules="[{ required: true, errorMessage: '请选择日期' }]">
  487. <uni-datetime-picker
  488. class="datetime-picker"
  489. type="date"
  490. returnType="timestamp"
  491. v-model="item.reportDate"
  492. :border="false"
  493. :disabled="disabled('edit')"
  494. @change="inputCurrentDepth()" />
  495. </uni-forms-item>
  496. <uni-forms-item :label="`${$t('ruiDu.timeNode')}:`" required>
  497. <view
  498. class="item-content"
  499. @click="disabled('edit') ? '' : handleClickTimeRangeItem(index)">
  500. <view class="time-range-item" v-if="item.startTime && item.endTime">
  501. {{ item.startTime }} 至 {{ item.endTime }}
  502. </view>
  503. <view class="time-range-item" v-else> '请选择' </view>
  504. </view>
  505. </uni-forms-item>
  506. <uni-forms-item label="时长(H)">
  507. <span class="readOnly">{{ item.duration }}</span>
  508. </uni-forms-item>
  509. <uni-forms-item
  510. label="工况"
  511. required
  512. :name="['reportDetails', index, 'currentOperation']"
  513. :rules="[{ required: true, errorMessage: '请输入工况' }]">
  514. <uni-easyinput
  515. type="textarea"
  516. autoHeight
  517. v-bind="defaultProps"
  518. :disabled="disabled('edit')"
  519. v-model="item.currentOperation"
  520. :maxlength="2000" />
  521. </uni-forms-item>
  522. <uni-forms-item
  523. label="结束井深(m)"
  524. required
  525. :name="['reportDetails', index, 'currentDepth']"
  526. :rules="[
  527. { required: true, errorMessage: '请输入结束深度' },
  528. { validateFunction: validateLastCurrentDepth },
  529. ]">
  530. <uni-easyinput
  531. type="number"
  532. v-bind="defaultProps"
  533. :disabled="disabled('edit')"
  534. v-model.number="item.currentDepth"
  535. @input="val => inputCurrentDepth(val, index)" />
  536. </uni-forms-item>
  537. <uni-forms-item
  538. label="详情"
  539. required
  540. :name="['reportDetails', index, 'constructionDetail']"
  541. :rules="[{ required: true, errorMessage: '请输入详情' }]">
  542. <uni-easyinput
  543. type="textarea"
  544. autoHeight
  545. v-bind="defaultProps"
  546. :disabled="disabled('edit')"
  547. v-model="item.constructionDetail"
  548. :maxlength="2000" />
  549. </uni-forms-item>
  550. <uni-forms-item v-if="!disabled('edit')" label="操作">
  551. <button
  552. type="warn"
  553. size="mini"
  554. class="detail-btn"
  555. @click="removeReportDetailRow(index)">
  556. 删除
  557. </button>
  558. </uni-forms-item>
  559. </template>
  560. <uv-divider text="生产时间" textPosition="left"></uv-divider>
  561. <uni-forms-item
  562. label="进尺工作时间(H)"
  563. name="drillingWorkingTime"
  564. required>
  565. <uni-easyinput
  566. type="number"
  567. v-bind="defaultProps"
  568. :class="{ 'orange-text': orange }"
  569. :disabled="disabled('edit')"
  570. v-model="form.drillingWorkingTime" />
  571. </uni-forms-item>
  572. <uni-forms-item
  573. label="其它生产时间(H)"
  574. name="otherProductionTime"
  575. required>
  576. <uni-easyinput
  577. type="number"
  578. v-bind="defaultProps"
  579. :class="{ 'orange-text': orange }"
  580. :disabled="disabled('edit')"
  581. v-model="form.otherProductionTime" />
  582. </uni-forms-item>
  583. <uv-divider text="非生产时间" textPosition="left"></uv-divider>
  584. <uni-forms-item
  585. v-for="field in NON_PROD_FIELDS"
  586. :key="field.key"
  587. :label="field.label + '(H)'"
  588. :name="field.key">
  589. <uni-easyinput
  590. type="number"
  591. :class="{ 'orange-text': orange }"
  592. v-bind="defaultProps"
  593. :disabled="disabled('edit')"
  594. v-model="form[field.key]" />
  595. </uni-forms-item>
  596. <uni-forms-item label="其他非生产原因" name="otherNptReason">
  597. <uni-easyinput
  598. type="textarea"
  599. autoHeight
  600. v-bind="defaultProps"
  601. v-model="form.otherNptReason"
  602. :disabled="disabled('edit')"
  603. :maxlength="1000" />
  604. </uni-forms-item>
  605. <uni-forms-item
  606. v-if="type.includes('approval')"
  607. label="审批意见"
  608. name="opinion">
  609. <uni-easyinput
  610. type="textarea"
  611. autoHeight
  612. v-bind="defaultProps"
  613. :disabled="disabled('approval')"
  614. v-model="form.opinion"
  615. :maxlength="1000" />
  616. </uni-forms-item>
  617. </uni-forms>
  618. </view>
  619. <tpf-time-range
  620. ref="reportDetailsTimeRangeRef"
  621. :startTime="startTime"
  622. :startDefaultTime="startDefaultTime"
  623. :endTime="endTime"
  624. :endDefaultTime="endDefaultTime"
  625. @timeRange="reportDetailsTimeRange"></tpf-time-range>
  626. </template>
  627. <style lang="scss" scoped>
  628. .content {
  629. background-color: white;
  630. padding: 16px 16px;
  631. border-radius: 8px;
  632. box-sizing: border-box;
  633. }
  634. .uni-forms {
  635. margin-top: 10px;
  636. height: 100%;
  637. .uni-form {
  638. height: 100%;
  639. }
  640. .uni-forms-item {
  641. display: flex;
  642. align-items: center;
  643. flex: 1;
  644. margin-bottom: 6px;
  645. border-bottom: 1px dashed #cacccf;
  646. }
  647. :deep(.uni-forms-item__content) {
  648. text-align: right;
  649. .readOnly {
  650. padding-right: 10px;
  651. }
  652. }
  653. :deep(.uni-forms-item__label) {
  654. height: 44px;
  655. font-weight: 500;
  656. font-size: 14px;
  657. color: #333333 !important;
  658. width: max-content !important;
  659. }
  660. :deep(.uni-select) {
  661. border: none;
  662. text-align: right;
  663. padding-right: 0;
  664. .uniui-bottom:before {
  665. content: "\e6b5" !important;
  666. font-size: 16px !important;
  667. }
  668. }
  669. :deep(.uni-easyinput__content-textarea) {
  670. min-height: inherit;
  671. margin: 10px;
  672. }
  673. :deep(.is-disabled) {
  674. color: #333333 !important;
  675. }
  676. :deep(.red-text > .is-disabled) {
  677. color: rgb(220 38 38 / 0.8) !important;
  678. }
  679. :deep(.orange-text > .is-disabled) {
  680. color: rgb(234 88 12 / 0.8) !important;
  681. }
  682. :deep(.uni-select--disabled) {
  683. background-color: #fff;
  684. }
  685. }
  686. .red-text {
  687. color: rgb(220 38 38 / 0.8) !important;
  688. }
  689. .orange-text {
  690. color: rgb(234 88 12 / 0.8) !important;
  691. }
  692. .red {
  693. border: 1px solid rgb(254 226 226);
  694. color: rgb(220 38 38 / 0.8);
  695. background-color: rgb(254 226 226);
  696. }
  697. .orange {
  698. border: 1px solid rgb(254 215 170);
  699. color: rgb(234 88 12 / 0.8);
  700. background-color: rgb(254 215 170);
  701. }
  702. .tip {
  703. border-radius: 8px;
  704. border: 1px solid #e5e5e5;
  705. background-color: rgba(239, 246, 255, 0.8);
  706. box-sizing: border-box;
  707. padding: 10px;
  708. display: flex;
  709. flex-direction: column;
  710. gap: 6px;
  711. .item {
  712. display: flex;
  713. align-items: center;
  714. justify-content: space-between;
  715. font-size: 12px;
  716. .left {
  717. color: rgb(75 85 99);
  718. span {
  719. color: rgb(31 41 55);
  720. font-weight: 600;
  721. }
  722. }
  723. .right {
  724. display: inline-flex;
  725. align-items: center;
  726. border-radius: 4px;
  727. padding: 2px 4px;
  728. font-weight: 500;
  729. }
  730. }
  731. }
  732. .opinion {
  733. border-radius: 8px;
  734. border: 1px solid rgb(254 240 138);
  735. background-color: rgb(254 252 232);
  736. box-sizing: border-box;
  737. padding: 10px;
  738. display: flex;
  739. align-items: center;
  740. justify-content: space-between;
  741. font-size: 12px;
  742. margin-top: 10px;
  743. .left {
  744. font-weight: 600;
  745. color: rgb(133 77 14);
  746. }
  747. .right {
  748. font-weight: 500;
  749. color: rgb(75 85 99);
  750. }
  751. }
  752. :deep(.uv-divider__text) {
  753. color: #333 !important;
  754. }
  755. .detail-btn {
  756. margin: 0;
  757. margin-left: auto;
  758. float: right;
  759. }
  760. .time-range-item {
  761. margin: 10px;
  762. }
  763. .item-content {
  764. display: flex;
  765. align-items: center;
  766. justify-content: end;
  767. }
  768. .divider {
  769. margin: 0;
  770. transform: translateY(-7px);
  771. :deep(.uv-line) {
  772. border-width: 2px !important;
  773. border-color: rgb(41, 121, 255) !important;
  774. }
  775. }
  776. :deep(.datetime-picker) {
  777. .uniui-calendar {
  778. &::before {
  779. display: none;
  780. }
  781. }
  782. .uni-date-editor--x__disabled {
  783. opacity: 1 !important;
  784. }
  785. .uni-date__x-input {
  786. color: #333 !important;
  787. }
  788. }
  789. </style>