underwriting.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. <template>
  2. <div class="underwriting">
  3. <div class="title">
  4. <span class="text">影像信息</span>
  5. <el-popover :visible="imageTypeShow" placement="bottom-start" :width="600" trigger="click">
  6. <template #reference>
  7. <el-button plain type="primary" icon="Plus" size="small" @click="addImages">添加影像资料</el-button>
  8. </template>
  9. <imageTypeSelect ref="ImageTypeSelect" @close="handleImageTypeSelect"></imageTypeSelect>
  10. </el-popover>
  11. </div>
  12. <div class="images">
  13. <el-row :gutter="20">
  14. <el-col class="col-m-b-16" style="margin-bottom: 16px" :span="6" v-for="(item, index) in images" :key="index">
  15. <el-upload v-if="!item.fileUrl" :auto-upload="false" :show-file-list="false"@change="uploadImage($event, item)">
  16. <div class="upload-box">
  17. <div class="icon-box">
  18. <el-icon style="font-size: 20px"><Camera /></el-icon>
  19. <p>{{ item.label }}</p>
  20. </div>
  21. </div>
  22. </el-upload>
  23. <div class="fileInfo" v-else>
  24. <div class="file-box">
  25. <div class="btn-top">
  26. <img class="image-close" @click="deleteImage(item)" src="@/assets/images/close.png" />
  27. </div>
  28. <img class="file-img" :src="item.fileUrl" />
  29. <div class="btn-bottom">
  30. <el-upload class="width-50" :show-file-list="false" :auto-upload="false" accept=".png, .jpg, .jpeg" @change="uploadImage($event, item)" style="display: flex; align-items: center; justify-content: center; color: white">
  31. <el-icon><Upload /></el-icon>重新上传
  32. </el-upload>
  33. <div class="width-50" style="display: flex; align-items: center; justify-content: center; color: white; cursor:pointer;" @click="downloadImage(item)">
  34. <el-icon><Download /></el-icon>下载资料
  35. </div>
  36. </div>
  37. </div>
  38. </div>
  39. </el-col>
  40. </el-row>
  41. </div>
  42. <div class="title">
  43. <span class="text">特别约定</span>
  44. </div>
  45. <el-table
  46. ref="ClauseRefs"
  47. :data="tableData"
  48. row-key="id"
  49. @selection-change="selectionChange"
  50. >
  51. <el-table-column type="selection" width="50" align="center" :selectable="selectable"></el-table-column>
  52. <el-table-column label="特约类型" prop="riskCode" align="center">
  53. <template #default="scope">
  54. <div v-if="scope.row.riskCode == '0507'">交强</div>
  55. <div v-if="scope.row.riskCode == '0510'">商业</div>
  56. </template>
  57. </el-table-column>
  58. <el-table-column label="特约名称" prop="clauseName" align="center"></el-table-column>
  59. <el-table-column label="编码" prop="clauseCode" align="center"></el-table-column>
  60. <el-table-column label="特别约定内容" prop="" width="300" align="center">
  61. <template #default="scope">
  62. <div v-if="!scope.row.edit" @click="() => { scope.row.edit = true }">{{ scope.row.clauseContent }}</div>
  63. <el-input type="textarea" v-model="scope.row.clauseContent" v-if="scope.row.edit"></el-input>
  64. </template>
  65. </el-table-column>
  66. </el-table>
  67. <div class="footer">
  68. <el-button plain type="primary" @click="handleSubmit(false)">取消</el-button>
  69. <el-button type="primary" @click="handleSubmit(true)">提交核保</el-button>
  70. </div>
  71. </div>
  72. </template>
  73. <script setup lang="ts">
  74. import api from '@/api'
  75. import { ElMessage } from 'element-plus'
  76. import imageTypeSelect from './imageTypeSelect.vue'
  77. const ImageTypeSelect = ref()
  78. const emit = defineEmits(['close'])
  79. let images = ref([])
  80. // 添加影像资料
  81. let imageTypeShow = ref(false)
  82. const addImages = () => {
  83. imageTypeShow.value = true
  84. nextTick(() => {
  85. ImageTypeSelect.value.initEditData(images.value)
  86. })
  87. }
  88. const handleImageTypeSelect = (data) => {
  89. imageTypeShow.value = false
  90. if(data&&data.list?.length>0) {
  91. images.value = data.list
  92. }
  93. }
  94. // 图片删除
  95. const deleteImage = (item) => {
  96. item.fileUrl = ''
  97. item.imageId = ''
  98. item.fileName = ''
  99. }
  100. // 上传图片
  101. const uploadImage = async (file, item) => {
  102. let files = file.raw
  103. const params = new FormData(); // 声明formData数据类型
  104. params.append("file", files);
  105. params.append("type", "image");
  106. const { code, data, msg } = await api.commonApi.fileUpload(params)
  107. if(code == 200) {
  108. let result: any = {...data}
  109. item.fileUrl = result.downloadUrl
  110. item.imageId = result.id
  111. item.fileName = result.fileName
  112. } else {
  113. ElMessage({
  114. message: msg,
  115. type: 'error'
  116. })
  117. }
  118. }
  119. // 下载
  120. // 图片下载
  121. const download = (url, name) => {
  122. let image = new Image();
  123. // 解决跨域 Canvas 污染问题
  124. image.setAttribute("crossOrigin", "anonymous");
  125. image.onload = function () {
  126. let canvas = document.createElement("canvas");
  127. canvas.width = image.width;
  128. canvas.height = image.height;
  129. let context = canvas.getContext("2d");
  130. context.drawImage(image, 0, 0, image.width, image.height);
  131. let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
  132. let a = document.createElement("a"); // 生成一个a元素
  133. let event = new MouseEvent("click"); // 创建一个单击事件
  134. a.download = name; // 设置图片名称
  135. a.href = url; // 将生成的URL设置为a.href属性
  136. a.dispatchEvent(event); // 触发a的单击事件
  137. }
  138. image.src = url
  139. }
  140. const downloadImage = (item) => {
  141. download(item.fileUrl,item.fileName)
  142. }
  143. // 特别约定
  144. let tableData = ref([])
  145. let ClauseRefs = ref()
  146. let clauseList = ref([])
  147. const queryClauseData = () => {
  148. api.insurancePolicyApi.queryClauseData({
  149. order: {
  150. ordersNo: ordersNo.value
  151. }
  152. }).then((res: any) => {
  153. if(res.code == 200) {
  154. tableData.value = res.data.map((item) => {
  155. return {
  156. ...item,
  157. edit: false
  158. }
  159. })
  160. clauseList.value = tableData.value?.filter(item => item.clientStatus != '3')
  161. nextTick(() => {
  162. tableData.value?.forEach(item => {
  163. if(item.clientStatus != '3') {
  164. console.log(123123123123213123123213)
  165. ClauseRefs.value.toggleRowSelection(item, true)
  166. }
  167. })
  168. })
  169. } else {
  170. ElMessage({
  171. message: res.msg,
  172. type: 'warning'
  173. })
  174. }
  175. })
  176. }
  177. const selectable = (row) => !['2'].includes(row.clientStatus)
  178. const selectionChange = (val) => {
  179. clauseList.value = val
  180. }
  181. // 提交核保
  182. const handleSubmit = (bool) => {
  183. if(bool) {
  184. api.insurancePolicyApi.underwriting({
  185. order: {
  186. ordersNo: ordersNo.value
  187. },
  188. specialAppointmentsVos: [...clauseList.value]
  189. }).then((res: any) => {
  190. if(res.code === 200) {
  191. ElMessage({
  192. message: res.msg,
  193. type: 'success'
  194. })
  195. } else {
  196. ElMessage({
  197. message: res.msg,
  198. type: 'warning'
  199. })
  200. }
  201. })
  202. emit('close', false)
  203. } else {
  204. emit('close', false)
  205. }
  206. }
  207. //数据交互
  208. let ordersNo = ref('')
  209. const initEdit = (data) => {
  210. console.log('核保的数据', data)
  211. ordersNo.value = data.ordersNo
  212. images.value = data.list.map(item => {
  213. return {
  214. ...item,
  215. fileUrl: item.fileUrl || item.downloadUrl
  216. }
  217. })
  218. if(ordersNo.value) {
  219. queryClauseData()
  220. }
  221. }
  222. defineExpose({
  223. initEdit
  224. })
  225. </script>
  226. <style scoped lang="scss">
  227. .underwriting{
  228. max-height: 400px;
  229. overflow-y: auto;
  230. overflow-x: hidden;
  231. .title{
  232. display: flex;
  233. align-items: center;
  234. justify-content: flex-start;
  235. margin-bottom: 10px;
  236. .text{
  237. margin-right: 10px;
  238. border-left: 3px solid #00a0f4;
  239. padding-left: 10px;
  240. }
  241. }
  242. .upload-box{
  243. width: 208px;
  244. height: 130px;
  245. background: #EEEEEE;
  246. border: 1px solid #EEEEEE;
  247. border-radius: 4px;
  248. display: flex;
  249. align-items: center;
  250. justify-content: center;
  251. .icon-box{
  252. text-align: center;
  253. color: #999999;
  254. p{
  255. margin: 0 0;
  256. font-size: 14px;
  257. }
  258. }
  259. }
  260. .fileInfo{
  261. display: flex;
  262. align-items: center;
  263. justify-content: flex-start;
  264. //padding: 2px 20px;
  265. border-radius: 5px;
  266. margin: 0 10px;
  267. //&:hover{
  268. // background: #ccc;
  269. //}
  270. .fileName{
  271. width: 200px;
  272. overflow: hidden;
  273. text-overflow: ellipsis;
  274. white-space: nowrap;
  275. }
  276. .fileBtn{
  277. display: flex;
  278. align-items: center;
  279. .btn-icon{
  280. margin: 0 10px;
  281. font-size: 16px;
  282. cursor: pointer;
  283. &:hover{
  284. color: #00a0f4;
  285. }
  286. }
  287. }
  288. .file-box{
  289. position: relative;
  290. .btn-top{
  291. width: 100%;
  292. display: flex;
  293. align-items: center;
  294. justify-content: flex-end;
  295. position: absolute;
  296. top: 0;
  297. left: 0;
  298. .image-close{
  299. display: block;
  300. width: 12px;
  301. height: 12px;
  302. }
  303. }
  304. .file-img{
  305. display: block;
  306. width: 208px;
  307. height: 130px;
  308. border-radius: 5px;
  309. }
  310. .btn-bottom{
  311. position: absolute;
  312. left: 0;
  313. bottom: 0;
  314. z-index: 1000;
  315. display: flex;
  316. align-items: center;
  317. height: 24px;
  318. width: 100%;
  319. background: url("@/assets/images/btn-bg.png") no-repeat;
  320. background-size: 100% 100%;
  321. .width-50{
  322. width: 50%;
  323. }
  324. }
  325. }
  326. }
  327. .footer{
  328. display: flex;
  329. align-items: center;
  330. justify-content: flex-end;
  331. margin-top: 10px;
  332. }
  333. }
  334. </style>