설명 없음
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Culture.vue 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. <template>
  2. <div class="h5-container">
  3. <van-nav-bar title="安全环保文化" @click-left="onClickLeft" @click-right="handAdd">
  4. <template #right>
  5. <van-icon name="add" size="25" color="#000" />
  6. </template>
  7. </van-nav-bar>
  8. <van-search v-model="query.caseTitle" show-action placeholder="请输入案例标题" @search="onRefresh"
  9. @cancel="handdelectTitle" />
  10. <!-- 项目列表 -->
  11. <van-pull-refresh v-model="isRefreshing" success-text="刷新成功" @refresh="onRefresh">
  12. <van-list v-model:loading="isLoading" :finished="isFinished" finished-text="没有更多了" offset="200" @load="onLoad">
  13. <div v-for="(item, idx) in resultData" :key="item.id">
  14. <van-swipe-cell title-style="color: #007aff" style="height: 80px;" :ref="el => getSwipeCellRef(el, idx)">
  15. <template #default>
  16. <div class="swipe-cell-default">
  17. <van-cell style="min-height: 100px; padding: 0 0 0 0; display: flex; align-items: flex-start;" @click="edits(item)">
  18. <template #title>
  19. <div class="cell-title">
  20. {{ item.activityTitle }}
  21. </div>
  22. </template>
  23. <template #label>
  24. <div>案例编号:{{ item.caseNumber }} </div>
  25. <div>案例类型:{{ item.caseType }}</div>
  26. <div> 浏览量:{{item.viewCount}}</div>
  27. <!-- <div style="width: 112px" :class="getStatusClass(item.isFinish)">
  28. 类型:
  29. <span v-if="item.isFinish === '待学习'" style="width: 200px">待学习</span>
  30. <span v-else-if="item.isFinish === '已学习'" style="width: 200px">已学习</span>
  31. <span v-else-if="item.isFinish === '已扣除'" style="width: 200px">已扣除</span>
  32. </div>-->
  33. </template>
  34. </van-cell>
  35. <div class="swipe-cell-default-icon">
  36. <van-icon v-if="openStatus[idx]" name="arrow-double-left" @click.stop="openSwipe(idx)" />
  37. <van-icon v-else name="arrow-double-right" @click.stop="closeSwipe(idx)" />
  38. </div>
  39. </div>
  40. </template>
  41. <template #right>
  42. <van-button square class="delete-button" text="删除" v-show="item.canDelete" @click="handleDelete(item)" />
  43. </template>
  44. </van-swipe-cell>
  45. </div>
  46. </van-list>
  47. </van-pull-refresh>
  48. <!-- 删除确认弹窗 -->
  49. <van-dialog v-model:show="deleteDialogVisible" show-cancel-button @confirm="confirmDelete">
  50. <template #title>
  51. <div>删除确认</div>
  52. </template>
  53. <div style="padding: 30px;">确定要删除该项目吗?</div>
  54. </van-dialog>
  55. </div>
  56. </template>
  57. <script setup>
  58. import { ref, reactive, onMounted, getCurrentInstance, nextTick, toRaw } from 'vue';
  59. import { Dialog, showDialog, showSuccessToast, showToast, Toast } from 'vant';
  60. import tools from '@/tools'
  61. const { proxy } = getCurrentInstance();
  62. const onClickLeft = () => {
  63. history.back();
  64. };
  65. const headers = ref({
  66. token: localStorage.getItem('token'),
  67. userId: localStorage.getItem('userId'),
  68. dept: JSON.parse(localStorage.getItem('dept'))[0].deptCode
  69. });
  70. const switchIconState = (idx) => {
  71. openStatus.value[idx] = !openStatus.value[idx]
  72. openStatus.value = new Array(resultData.value.length).fill(true);
  73. }
  74. // const onClickRight = () =>{
  75. // searchShow.value = !searchShow.value;
  76. // }
  77. const searchShow = ref(false);
  78. const query = ref({
  79. caseNumber:'',
  80. caseTitle:'',
  81. })
  82. const tableData = ref([]);
  83. const selectedRows = ref([]);
  84. const dialogVisibleLook = ref(false);
  85. const deleteDialogVisible = ref(false);
  86. const currentDeleteItem = ref([]);
  87. const dialogVisible = ref(false);
  88. const dialogVisibleFile = ref(false);
  89. const date = ref(null);
  90. const kz = ref(true);
  91. import { useRouter } from 'vue-router';
  92. const router = useRouter();
  93. const handAdd = () => {
  94. router.push({ path: "/CultureList",
  95. query: {
  96. mark:-1
  97. } });
  98. };
  99. const goaddPeo = (item) => {
  100. router.push({
  101. path: '/addPeo',
  102. query: {
  103. data: JSON.stringify(item)
  104. }
  105. })
  106. }
  107. const edits = (row) => {
  108. const isOwner = String(row.addId) === currentUserId;
  109. kz.value = true;
  110. form.value = { ...row };
  111. router.push({ path: "/CultureList",
  112. query: {
  113. mark:1,
  114. data:JSON.stringify(form.value),
  115. readOnly: !isOwner ? 'true' : undefined
  116. } });
  117. //浏览量
  118. saveManagerRecord(form.value)
  119. };
  120. const saveManagerRecord = async (formValue) => {
  121. const payload = formValue;
  122. payload.viewCount = String((Number(payload.viewCount) || 0) + 1);
  123. var url = '/sgsafe/Manager/saveCulture';
  124. var param = {
  125. json: JSON.stringify(payload)
  126. };
  127. proxy.$axios.post(url, param).then(response => {
  128. if (response.data.code == '0') {
  129. getTableData();
  130. }
  131. });
  132. };
  133. const form = ref({
  134. caseNumber:'',
  135. caseTitle:'',
  136. caseSource:'',
  137. accidentLevel:'',
  138. accidentDept:'',
  139. accidentLocation:'',
  140. accidentTime:'',
  141. accidentType:'',
  142. accidentTags:'',
  143. casualtyCount:'',
  144. accidentSummary:'',
  145. preventiveMeasures:'',
  146. fileId:'',
  147. viewCount:'',
  148. downloadCount:''
  149. });
  150. const isRefreshing = ref(false);
  151. const isLoading = ref(false);
  152. const isFinished = ref(false);
  153. const currentPage = ref(1);
  154. const pageSize = ref(10);
  155. const totalRows = ref(0);
  156. const resultData = ref([]);
  157. const dept=localStorage.getItem("dept")[0].deptCode;
  158. const currentUserId = String(localStorage.getItem('userId'));
  159. const getTableData = async () => {
  160. var url = '/sgsafe/Manager/queryCulture'
  161. var param = {
  162. page: currentPage.value,
  163. rows: pageSize.value,
  164. params: JSON.stringify(query.value)
  165. }
  166. const response = await proxy.$axios.get(url, param);
  167. if (response.data.code == 0) {
  168. tableData.value = response.data.data.records.map(item => ({
  169. ...item,
  170. canDelete: String(item.addId) === currentUserId
  171. }));
  172. console.log('列表数据',tableData.value)
  173. totalRows.value = response.data.data.total;
  174. } else {
  175. showToast({
  176. type: 'error',
  177. message: '操作失败!' + response.data.msg
  178. });
  179. }
  180. };
  181. const ruleIds = ref([]);
  182. const onRefresh = () => {
  183. basicReset();
  184. onLoad();
  185. };
  186. //*************************************
  187. //定义字典集合
  188. const dicList = ref([])
  189. const getDicList = () => {
  190. tools.dic.getDicList([ 'case_type','SEX', 'case_source','accident_level','accident_type','sgsafe_taccidentTags']).then((response => {
  191. console.log(JSON.stringify(response.data.data))
  192. dicList.value = response.data.data
  193. }))
  194. }
  195. const onLoad = async () => {
  196. if (isRefreshing.value) {
  197. resultData.value = [];
  198. currentPage.value = 1;
  199. isRefreshing.value = false;
  200. }
  201. getDicList()
  202. try {
  203. await getTableData();
  204. if (pageSize.value * currentPage.value < totalRows.value) {
  205. resultData.value = [...resultData.value, ...tableData.value];
  206. openStatus.value = new Array(resultData.value.length).fill(true);
  207. currentPage.value++;
  208. } else {
  209. resultData.value = [...resultData.value, ...tableData.value];
  210. openStatus.value = new Array(resultData.value.length).fill(true);
  211. isFinished.value = true;
  212. }
  213. console.log('resultData',resultData.value)
  214. } catch (error) {
  215. console.log(error);
  216. isFinished.value = true;
  217. } finally {
  218. isLoading.value = false;
  219. }
  220. };
  221. /* 通用方法: 重置list数据 */
  222. const basicReset = () => {
  223. isFinished.value = false;
  224. isLoading.value = true;
  225. currentPage.value = 1;
  226. resultData.value = [];
  227. };
  228. /*onMounted(() => {
  229. handleSearch();
  230. });
  231. const handleSearch = () => {
  232. /!* currentPage.value = 1;
  233. isFinished.value = false;
  234. tableData.value = [];*!/
  235. basicReset()
  236. onLoad()
  237. };*/
  238. const handdelectNumber = () => {
  239. query.value.caseNumber = '';
  240. onRefresh()
  241. };
  242. const handdelectTitle = () => {
  243. query.value.caseTitle = '';
  244. onRefresh()
  245. };
  246. // 定义生成编号的函数
  247. const generateCode = () => {
  248. // 获取当前日期并格式化为 YYYYMMDD
  249. const now = new Date();
  250. const year = now.getFullYear();
  251. const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始,需加1
  252. const day = String(now.getDate()).padStart(2, '0');
  253. const formattedDate = `${year}${month}${day}`;
  254. // 时间部分:HHmmss
  255. const hours = String(now.getHours()).padStart(2, '0');
  256. const minutes = String(now.getMinutes()).padStart(2, '0');
  257. const seconds = String(now.getSeconds()).padStart(2, '0');
  258. const formattedTime = `${hours}${minutes}${seconds}`;
  259. // 模拟生成三位流水号(可以根据需要替换为递增逻辑)
  260. const sequenceNumber = Math.floor(Math.random() * 1000); // 随机生成 0-999
  261. const paddedSequence = String(sequenceNumber).padStart(3, '0'); // 补零到三位
  262. // 拼接编号
  263. return `SGAL${formattedDate}${formattedTime}${paddedSequence}`;
  264. };
  265. // 使用 ref 存储生成的编号
  266. const generatedCode = ref(generateCode());
  267. // 定义重新生成编号的方法
  268. const regenerateCode = () => {
  269. generatedCode.value = generateCode();
  270. };
  271. const handleDetailLook = (row) => {
  272. form.value = { ...row };
  273. proxy.$router.push({
  274. name: 'taiZhang_detail',
  275. query: {
  276. form: form.value.id
  277. }
  278. });
  279. // dialogVisibleLook.value = true;
  280. };
  281. const deleteData=ref({})
  282. const handleDelete = (item) => {
  283. deleteData.value=item
  284. const now = new Date();
  285. const year = now.getFullYear();
  286. const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始
  287. const day = String(now.getDate()).padStart(2, '0');
  288. const hours = String(now.getHours()).padStart(2, '0');
  289. const minutes = String(now.getMinutes()).padStart(2, '0');
  290. const seconds = String(now.getSeconds()).padStart(2, '0');
  291. deleteData.value.cancelTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  292. deleteData.value.cancelFlag='1'
  293. var url = '/sgsafe/Manager/saveCulture';
  294. var param = {
  295. json: JSON.stringify(deleteData.value)
  296. };
  297. proxy.$axios.post(url, param).then(response => {
  298. if (response.data.code == '0') {
  299. showSuccessToast("删除成功")
  300. onRefresh();
  301. } else {
  302. }
  303. })
  304. };
  305. const confirmDelete = () => {
  306. for (let item of currentDeleteItem.value) {
  307. if (item.addId !== headers.value.userId) {
  308. showToast({
  309. type: 'warning',
  310. message: '只能删除自己添加的数据!'
  311. });
  312. return;
  313. }
  314. }
  315. if (currentDeleteItem.value[0].status !== '0' && currentDeleteItem.value[0].hdSelect !== '下发隐患'
  316. && currentDeleteItem.value[0].hdSelect !== '即查即改') {
  317. showToast({
  318. type: 'fail',
  319. message: '只有尚未提交流程的记录或回到起点的流程经过作废后才可以删除!'
  320. });
  321. return;
  322. }
  323. if (currentDeleteItem.value[0].status !== '2' && currentDeleteItem.value[0].hdSelect === '下发隐患'
  324. && currentDeleteItem.value[0].hdSelect !== '即查即改') {
  325. showToast({
  326. type: 'fail',
  327. message: '只有尚未提交流程的记录或回到起点的流程经过作废后才可以删除!'
  328. });
  329. return;
  330. }
  331. var url = 'sgsafe/Hiddendanger/remove';
  332. var param = {
  333. params: JSON.stringify({ ...currentDeleteItem.value.map(x => x.id) })
  334. };
  335. proxy.$axios.get(url, param).then(response => {
  336. if (response.data.code == 0) {
  337. showToast({
  338. type: 'success',
  339. message: '删除成功'
  340. });
  341. onRefresh();
  342. } else {
  343. showToast({
  344. type: 'fail',
  345. message: '操作失败!' + response.data.msg
  346. });
  347. }
  348. });
  349. };
  350. const resetForm = () => {
  351. form.value = {
  352. projectName: '',
  353. projectLeader: '',
  354. phone: '',
  355. dept: ''
  356. };
  357. };
  358. //处理人员code
  359. const repairLL = ref('');
  360. const repairOO = ref('');
  361. const acceptLL = ref('');
  362. const jsons = ref({});
  363. const reback = () => {
  364. // 返回逻辑
  365. };
  366. const deleteRow = (row) => {
  367. selectedRows.value = [row];
  368. handleDelete(row);
  369. };
  370. const deleteRowa = (row) => {
  371. deleteRow(row);
  372. };
  373. /**
  374. * 按钮实现swipe-cell滑动
  375. */
  376. const openStatus = ref([])
  377. const swipeCellRefs = ref([])
  378. const getSwipeCellRef = (el, index) => {
  379. if (el) {
  380. swipeCellRefs.value[index] = el;
  381. }
  382. }
  383. const openSwipe = (idx) => {
  384. openStatus.value = new Array(resultData.value.length).fill(true);
  385. if (idx >= 0 && idx < swipeCellRefs.value.length) {
  386. openStatus.value[idx] = false
  387. swipeCellRefs.value[idx].open('right')
  388. }
  389. document.addEventListener('click', handleDocumentClick)
  390. }
  391. /**
  392. * 当点击滑动单元格时,开始监听点击事件
  393. */
  394. const handleDocumentClick = (event) => {
  395. openStatus.value = new Array(resultData.value.length).fill(true);
  396. }
  397. const closeSwipe = (idx) => {
  398. if (idx >= 0 && idx < swipeCellRefs.value.length) {
  399. openStatus.value[idx] = true
  400. swipeCellRefs.value[idx].close()
  401. }
  402. }
  403. // *********************************** 事故案例 ************************************************
  404. </script>
  405. <style scoped>
  406. .h5-container {
  407. width: 100%;
  408. padding: 5px;
  409. box-sizing: border-box;
  410. }
  411. .status-pending {
  412. background-color: #fff3cd;
  413. color: #856404;
  414. padding: 2px 4px;
  415. border-radius: 4px;
  416. }
  417. .status-registered {
  418. background-color: #d1ecf1;
  419. color: #0c5460;
  420. padding: 2px 4px;
  421. border-radius: 4px;
  422. }
  423. .status-analyzing {
  424. background-color: #fff8e1;
  425. color: #ff8f00;
  426. padding: 2px 4px;
  427. border-radius: 4px;
  428. }
  429. .status-rectifying {
  430. background-color: #e8f5e9;
  431. color: #2e7d32;
  432. padding: 2px 4px;
  433. border-radius: 4px;
  434. }
  435. .status-accepting {
  436. background-color: #e3f2fd;
  437. color: #1565c0;
  438. padding: 2px 2px;
  439. border-radius: 2px;
  440. }
  441. .status-closed {
  442. background-color: #f8bbd0;
  443. color: #b71c1c;
  444. padding: 2px 2px;
  445. border-radius: 2px;
  446. }
  447. .status-finished {
  448. background-color: #e8eaf6;
  449. color: #311b92;
  450. padding: 2px 2px;
  451. border-radius: 2px;
  452. }
  453. .status-unknown {
  454. background-color: #efebe9;
  455. color: #424242;
  456. padding: 2px 2px;
  457. border-radius: 2px;
  458. }
  459. .cell-title {
  460. display: -webkit-box;
  461. /* 旧版弹性盒子模型 */
  462. -webkit-box-orient: vertical;
  463. /* 内容垂直排列 */
  464. -webkit-line-clamp: 2;
  465. /* 限制显示行数 */
  466. overflow: hidden;
  467. /* 超出隐藏 */
  468. text-overflow: ellipsis;
  469. /* 省略号 */
  470. line-height: 1.5;
  471. /* 可选:设置行高 */
  472. max-height: calc(1.5em * 2);
  473. /* 可选:根据行高限制最大高度 */
  474. font-size: 16px;
  475. font-weight: bold;
  476. color: #333;
  477. /* 字号 */
  478. }
  479. .swipe-cell-default {
  480. display: flex;
  481. background-color: #ffffff;
  482. justify-content: center;
  483. align-items: center;
  484. }
  485. .swipe-cell-default-icon {
  486. width: 60px;
  487. display: flex;
  488. justify-content: center;
  489. }
  490. .delete-button {
  491. height: 100%;
  492. border: none;
  493. color: #ff0000;
  494. background-image: url('@/assets/img/del.png');
  495. background-size: auto 100%;
  496. background-repeat: no-repeat;
  497. }
  498. .submit-button {
  499. height: 100%;
  500. border: none;
  501. color: #07c160;
  502. background-image: url('@/assets/img/sub.png');
  503. background-size: auto 100%;
  504. background-repeat: no-repeat;
  505. }
  506. .subsuccess {
  507. height: 100%;
  508. border: none;
  509. color: #07c160;
  510. background-image: url('@/assets/img/sub1.png');
  511. background-size: auto 100%;
  512. background-repeat: no-repeat;
  513. }
  514. .single-line-text {
  515. white-space: nowrap; /* 强制不换行 */
  516. overflow: hidden; /* 超出部分隐藏 */
  517. text-overflow: ellipsis; /* 超出显示省略号 ... */
  518. width: 100%; /* 或指定宽度 */
  519. box-sizing: border-box;
  520. }
  521. </style>