policy.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. <template>
  2. <HcCard>
  3. <template #header>
  4. <div class="w-36">
  5. <el-select v-model="searchForm.areaId" block clearable placeholder="请选择区域" size="large">
  6. <el-option v-for="item in areaType" :key="item.id" :label="item.areaName" :value="item.id" />
  7. </el-select>
  8. </div>
  9. <div class="w-36 ml-4">
  10. <el-date-picker v-model="searchForm.startDate" class="block" type="date" value-format="YYYY-MM-DD" placeholder="开始日期" clearable size="large" />
  11. </div>
  12. <div class="mx-2">
  13. ~
  14. </div>
  15. <div class="w-36">
  16. <el-date-picker v-model="searchForm.endDate" class="block" type="date" value-format="YYYY-MM-DD" placeholder="结束日期" clearable size="large" />
  17. </div>
  18. <div class="w-48 ml-2">
  19. <el-input v-model="searchForm.name" clearable placeholder="请输入名称进行查询" size="large" />
  20. </div>
  21. <div class="ml-4">
  22. <el-button type="primary" size="large" @click="searchClick">
  23. <HcIcon name="search-2" />
  24. <span>搜索</span>
  25. </el-button>
  26. </div>
  27. </template>
  28. <template #extra>
  29. <el-button size="large" type="primary" hc-btn @click="addRowClick">
  30. <HcIcon name="add" />
  31. <span>新增</span>
  32. </el-button>
  33. <el-button size="large" type="danger" hc-btn @click="batchClick">
  34. <HcIcon name="delete-bin" />
  35. <span>删除</span>
  36. </el-button>
  37. </template>
  38. <HcTable ref="tableListRef" :column="tableColumn" :datas="tableData" :loading="tableLoading" is-check :disabled="tableCheckedKeys.length < 1" @selection-change="tableSelectionChange">
  39. <template #action="{ row, index }">
  40. <el-button size="small" type="warning" @click="previewPdf(row)">
  41. 查看附件
  42. </el-button>
  43. <el-button size="small" type="primary" @click="editRowClick(row)">
  44. 编辑
  45. </el-button>
  46. <el-button size="small" type="danger" @click="delClickRow(row)">
  47. 删除
  48. </el-button>
  49. </template>
  50. </HcTable>
  51. <template #action>
  52. <HcPages :pages="searchForm" @change="pageChange" />
  53. </template>
  54. <!-- 新增/编辑 -->
  55. <HcDialog is-to-body bg-color="white" :show="rowModal" :title="formModel.id ? '编辑' : '新增'" widths="62rem" :loading="submitLoading" @save="rowModalSave" @close="rowModalClose">
  56. <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="left" label-width="auto" size="large">
  57. <div class="flex">
  58. <div class="flex-1 mr-4">
  59. <el-form-item label="编号" prop="number">
  60. <el-input v-model="formModel.number" />
  61. </el-form-item>
  62. <el-form-item label="名称" prop="name">
  63. <el-input v-model="formModel.name" />
  64. </el-form-item>
  65. <el-form-item label="所属区域:" prop="areaId">
  66. <el-select v-model="formModel.areaId" block>
  67. <el-option v-for="item in areaType" :key="item.id" :label="item.areaName" :value="item.id" />
  68. </el-select>
  69. </el-form-item>
  70. <el-form-item label="多个文件" prop="list">
  71. <HcFormUpload v-model="formModel.list" :src="filename" type="list" :preview="false" :is-delete="true" @item="formItemClick" @upload="formItemUpload" @change="formItemChange" />
  72. </el-form-item>
  73. </div>
  74. <div class="flex-1 ml-4">
  75. <el-form-item label="备注:">
  76. <el-input v-model="formModel.remark" type="textarea" :autosize="{ minRows: 6, maxRows: 10 }" />
  77. </el-form-item>
  78. </div>
  79. </div>
  80. </el-form>
  81. </HcDialog>
  82. <HcUploadFile ref="HcUploadFileRef" :options="UploadFileOptions" :params="{ projectId }" @finish="UploadFileFinish" @success="HcUploadFileSuccess" />
  83. </HcCard>
  84. </template>
  85. <script setup>
  86. import { onActivated, onMounted, ref } from 'vue'
  87. import { getTokenHeader } from '~src/api/request/header'
  88. import policyApi from '~api/base/policy.js'
  89. import { useAppStore } from '~src/store'
  90. import { arrToId, formValidate, getArrValue, getObjValue } from 'js-fast-way'
  91. import { getAllCounty } from '~api/other'
  92. import { delMessageV2 } from '~com/message/index.js'
  93. const useAppState = useAppStore()
  94. const projectId = ref(useAppState.getProjectId)
  95. onActivated(()=>{
  96. getAreaType()
  97. })
  98. onMounted(()=>{
  99. getTableData()
  100. })
  101. //上传配置
  102. const HcUploadFileRef = ref(null)
  103. const UploadFileOptions = {
  104. headers: getTokenHeader(),
  105. url:'/api/blade-land/attachmentInfo/add-file',
  106. accept_tip:'只能上传doc或pdf文件',
  107. accept:'application/pdf,.doc,.pdf,.docx,application/msword',
  108. }
  109. //区域
  110. const areaType = ref([])
  111. //获取区域
  112. const getAreaType = async ()=>{
  113. const { error, code, data } = await getAllCounty({
  114. projectId: projectId.value,
  115. })
  116. if (!error && code === 200) {
  117. areaType.value = getArrValue(data)
  118. } else {
  119. areaType.value = []
  120. }
  121. }
  122. //搜索表单
  123. const searchForm = ref({
  124. areaId: null, name: null, startDate: null, endDate: null,
  125. current: 1, size: 20, total: 0,
  126. })
  127. //搜索
  128. const searchClick = () => {
  129. searchForm.value.current = 1
  130. getTableData()
  131. }
  132. //分页被点击
  133. const pageChange = ({ current, size }) => {
  134. searchForm.value.current = current
  135. searchForm.value.size = size
  136. getTableData()
  137. }
  138. //获取数据
  139. const tableLoading = ref(false)
  140. const tableColumn = [
  141. { key: 'number', name: '编号', width: '120' },
  142. { key: 'name', name: '名称' },
  143. { key: 'uploadDate', name: '上传日期', width: '140', align: 'center' },
  144. { key: 'remark', name: '备注', width: '200', isTooltip: true },
  145. { key: 'action', name: '操作', width: '220', align: 'center' },
  146. ]
  147. const tableData = ref([
  148. ])
  149. const getTableData = async () => {
  150. tableLoading.value = true
  151. const { error, code, data } = await policyApi.getPage({
  152. ...searchForm.value,
  153. projectId: projectId.value,
  154. type:1,
  155. })
  156. tableLoading.value = false
  157. if (!error && code === 200) {
  158. tableData.value = getArrValue(data['records'])
  159. searchForm.value.total = data['total'] || 0
  160. } else {
  161. tableData.value = []
  162. searchForm.value.total = 0
  163. }
  164. }
  165. //多选
  166. const tableListRef = ref(null)
  167. const tableCheckedKeys = ref([])
  168. const tableSelectionChange = (rows) => {
  169. tableCheckedKeys.value = rows.filter((item) => {
  170. return (item ?? '') !== ''
  171. })
  172. }
  173. //弹窗
  174. const rowModal = ref(false)
  175. const formRef = ref(null)
  176. const formModel = ref({ list:[] })
  177. const formRules = {
  178. number: [{ required: true, message: '请输入编号', trigger: 'blur' }],
  179. name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
  180. areaId: [{ required: true, message: '请选择所属区域', trigger: 'change' }],
  181. remark: [{ required: true, message: '请输入备注', trigger: 'blur' }],
  182. list:[{ required: true, message: '请上传附件', trigger: 'blur' }],
  183. }
  184. //新增
  185. const addRowClick = () => {
  186. formModel.value = { list:[] }
  187. rowModal.value = true
  188. filename.value = ''
  189. }
  190. //查看附件
  191. const previewPdf = (row) => {
  192. const { pdfUrl } = row
  193. if (pdfUrl) {
  194. window.open(pdfUrl, '_blank')
  195. } else {
  196. window.$message.warning('文件不存在')
  197. }
  198. }
  199. //编辑
  200. const editRowClick = (row) => {
  201. getDetail(row.id)
  202. rowModal.value = true
  203. }
  204. //获取详情
  205. const getDetail = async (id)=>{
  206. const { error, code, data } = await policyApi.getDetail({
  207. id,
  208. })
  209. if (!error && code === 200) {
  210. formModel.value = getObjValue(data)
  211. const list = formModel.value['list'] || []
  212. let namearr = []
  213. list.forEach((ele)=>{
  214. namearr.push(ele.name)
  215. })
  216. filename.value = namearr.join(',')
  217. } else {
  218. formModel.value = { list:[] }
  219. filename.value = ''
  220. }
  221. }
  222. //保存
  223. const submitLoading = ref(false)
  224. const rowModalSave = async () => {
  225. const res = await formValidate(formRef.value)
  226. if (res) {
  227. submitLoading.value = true
  228. //发起请求
  229. const form = formModel.value
  230. form.projectId = projectId.value
  231. form.type = 1
  232. const { error, code, msg } = await policyApi.addOrUpdate(form)
  233. //判断状态
  234. submitLoading.value = false
  235. if (!error && code === 200) {
  236. window.$message?.success(msg)
  237. rowModal.value = false
  238. getTableData()
  239. }
  240. }
  241. }
  242. //关闭弹窗
  243. const rowModalClose = () => {
  244. rowModal.value = false
  245. formModel.value = {}
  246. }
  247. //上传
  248. const formItemUpload = () => {
  249. HcUploadFileRef?.value?.cancelUpload()
  250. HcUploadFileRef.value?.selectFile()
  251. }
  252. const formItemClick = async ({ item, index }) => {
  253. console.log(item, 'item')
  254. }
  255. //文件变化
  256. const formItemChange = (src, index) => {
  257. formModel.value.list.splice(index, 1)
  258. }
  259. //文件上传完成
  260. const UploadFileFinish = ()=>{
  261. HcUploadFileRef?.value.setModalShow(false)
  262. }
  263. const filename = ref('')
  264. // 文件上传成功的回调
  265. const HcUploadFileSuccess = ({ resData }) => {
  266. formModel.value.list.push(resData)
  267. const { name } = resData
  268. if (filename.value) {
  269. filename.value = filename.value + ',' + name
  270. } else {
  271. filename.value = name
  272. }
  273. }
  274. //删除
  275. const delClickRow = (row)=>{
  276. delMessageV2(async (action, instance, done) => {
  277. if (action === 'confirm') {
  278. instance.confirmButtonLoading = true
  279. removeRow([row.id])
  280. instance.confirmButtonLoading = false
  281. done()
  282. } else {
  283. done()
  284. }
  285. })
  286. }
  287. const removeRow = async (id)=>{
  288. const { error, code } = await policyApi.remove( id, false)
  289. //判断状态
  290. if (!error && code === 200) {
  291. window.$message?.success('删除成功')
  292. getTableData()
  293. } else {
  294. window.$message?.error('删除失败')
  295. }
  296. }
  297. const batchClick = ()=>{
  298. const rows = tableCheckedKeys.value
  299. const ids = arrToId(rows).split(',')
  300. delMessageV2(async (action, instance, done) => {
  301. if (action === 'confirm') {
  302. instance.confirmButtonLoading = true
  303. removeRow(ids)
  304. instance.confirmButtonLoading = false
  305. done()
  306. } else {
  307. done()
  308. }
  309. })
  310. }
  311. </script>