特易招,招聘小程序
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.

468 lines
11 KiB

11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
10 months ago
11 months ago
10 months ago
10 months ago
10 months ago
11 months ago
10 months ago
10 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
10 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
11 months ago
10 months ago
10 months ago
11 months ago
  1. <template>
  2. <view class="page">
  3. <navbar title="编辑模板" leftClick @leftClick="$utils.navigateBack" />
  4. <view class="title">
  5. <input type="text" placeholder="请输入标题" v-model="form.title"/>
  6. </view>
  7. <view style="padding: 25rpx;background-color: #fff;">
  8. <canvas-drag ref="canvasRef"
  9. id="canvas-drag" :graph="graph"
  10. :width="width" :height="height"
  11. @onDrawArrChange="onDrawArrChange"
  12. enableUndo="true"></canvas-drag>
  13. </view>
  14. <view class="btn-list" v-if="imageArr.length > 0">
  15. <view class="uni-color-btn" @tap="pro">上一页</view>
  16. <view>{{ imagesIndex + 1 }}/{{ imageArr.length }}</view>
  17. <view class="uni-color-btn" @tap="next">下一页</view>
  18. </view>
  19. <view class="btn-list">
  20. <!-- <view class="uni-color-btn" @tap="onAddImage">新建签名</view> -->
  21. <view class="uni-color-btn" @tap="onChangeBgImage">导入合同</view>
  22. <view class="uni-color-btn" @tap="onUndo">后退</view>
  23. <!-- <view class="uni-color-btn" @tap="onClearCanvas">清空</view> -->
  24. <view class="uni-color-btn" @tap="submit">保存</view>
  25. <!-- <view class="uni-color-btn" @tap="onExportJSON">导出模板</view> -->
  26. <!-- <view class="uni-color-btn" @tap="onAddText">添加文字</view> -->
  27. <view class="uni-color-btn" @tap="previewContract" v-if="form.template">预览合同</view>
  28. </view>
  29. </view>
  30. </template>
  31. <script>
  32. import canvasDrag from "../components/canvas-drag/index";
  33. import setData from "../components/canvas-drag/setData.js";
  34. import wxBase64src from '@/utils/wxBase64src.js'
  35. export default {
  36. components: {
  37. canvasDrag
  38. },
  39. mixins : [setData],
  40. data() {
  41. return {
  42. height: 750,
  43. width: 700,
  44. drawArr : {},
  45. form : {
  46. template : '',
  47. employeePage : 0,//求职者(乙方)签字页码
  48. employeePosition : '',//求职者(乙方)签字坐标
  49. bossPage : 0,//招聘者(甲方)签字页码
  50. bossPosition : '',//招聘者(甲方)签字坐标
  51. title : '',
  52. },
  53. imagesIndex : 0,
  54. imageArr : [],
  55. id : 0,
  56. }
  57. },
  58. onLoad({id}) {
  59. // uni.request({
  60. // url : 'http://192.168.1.5:5173/arr',
  61. // method: 'GET',
  62. // success : res => {
  63. // this.imageArr = res.data
  64. // this.onChangeBgImage()
  65. // }
  66. // })
  67. this.id = id
  68. this.getDetail()
  69. },
  70. mounted() {
  71. console.log("mounted mounted mounted");
  72. },
  73. methods: {
  74. // async pro(){
  75. // if(this.imagesIndex == 0){
  76. // uni.showToast({
  77. // title: '已经是第一页了'
  78. // })
  79. // return
  80. // }
  81. // this.imagesIndex--
  82. // await wxBase64src.unlink()
  83. // this.changeBgImage()
  84. // },
  85. // async next(){
  86. // if(this.imagesIndex == this.imageArr.length - 1){
  87. // uni.showToast({
  88. // title: '已经是最后一页了'
  89. // })
  90. // return
  91. // }
  92. // this.imagesIndex++
  93. // await wxBase64src.unlink()
  94. // this.changeBgImage()
  95. // },
  96. async pro(){
  97. if(this.imagesIndex == 0){
  98. uni.showToast({
  99. title: '已经是第一页了'
  100. })
  101. return
  102. }
  103. this.imagesIndex--
  104. await wxBase64src.unlink()
  105. // 强制重新渲染canvas
  106. this.$nextTick(async () => {
  107. await this.changeBgImage()
  108. })
  109. },
  110. async next(){
  111. if(this.imagesIndex == this.imageArr.length - 1){
  112. uni.showToast({
  113. title: '已经是最后一页了'
  114. })
  115. return
  116. }
  117. this.imagesIndex++
  118. await wxBase64src.unlink()
  119. // 强制重新渲染canvas
  120. this.$nextTick(async () => {
  121. await this.changeBgImage()
  122. })
  123. },
  124. // 预览合同
  125. previewContract(){
  126. uni.downloadFile({
  127. url : this.form.template,
  128. success : res => {
  129. uni.openDocument({
  130. filePath: res.tempFilePath,
  131. })
  132. }
  133. })
  134. },
  135. // 签名位置更新时
  136. onDrawArrChange(arr){
  137. console.log(arr);
  138. this.drawArr = arr
  139. },
  140. /**
  141. * 添加签名位置
  142. */
  143. onAddImage() {
  144. // wx.chooseImage({
  145. // success: res => {
  146. // this.setData({
  147. // graph: {
  148. // w: 100,
  149. // h: 50,
  150. // type: 'image',
  151. // url: res.tempFilePaths[0]
  152. // }
  153. // });
  154. // }
  155. // });
  156. let a = {}
  157. let b = {}
  158. if(this.id){
  159. a = JSON.parse(this.form.bossPosition)
  160. b = JSON.parse(this.form.employeePosition)
  161. for(let ak in a){
  162. a[ak] = this.$utils.screenSystemInfoInt(a[ak]) - 0
  163. }
  164. for(let bk in b){
  165. b[bk] = this.$utils.screenSystemInfoInt(b[bk]) - 0
  166. }
  167. console.log(a, b);
  168. }
  169. uni.getImageInfo({
  170. src: this.configList.config_sign_a,
  171. // src: 'https://img.teyizhao.com/2025-02-07/3d837c0e-91f4-4682-82d9-a04c2af737e8.png',
  172. success : res => {
  173. this.setData({
  174. graph: {
  175. id : 'a',
  176. w: a.w || 100,
  177. h: a.h || 50,
  178. x: a.x || 30,
  179. y: a.y || 30,
  180. type: 'image',
  181. url : res.path
  182. }
  183. });
  184. },
  185. fail(e) {
  186. console.log(e);
  187. }
  188. })
  189. uni.getImageInfo({
  190. src: this.configList.config_sign_b,
  191. // src: 'https://img.teyizhao.com/2025-02-07/af4786c0-7b62-4a86-a090-9f28eca3674a.png',
  192. success : res => {
  193. this.setData({
  194. graph: {
  195. id : 'b',
  196. w: b.w || 100,
  197. h: b.h || 50,
  198. x: b.x || 160,
  199. y: b.y || 30,
  200. type: 'image',
  201. url : res.path
  202. }
  203. });
  204. },
  205. fail(e) {
  206. console.log(e);
  207. }
  208. })
  209. },
  210. /**
  211. * 导入合同
  212. */
  213. async onChangeBgImage() {
  214. let self = this
  215. let pdfUrl = await self.loadFDP()
  216. this.form.template = pdfUrl
  217. await this.pdf2imagebase64()
  218. this.changeBgImage()
  219. },
  220. // async changeBgImage(){
  221. // let self = this
  222. // let src = await wxBase64src.base64src(this.imageArr[this.imagesIndex])
  223. // uni.getImageInfo({
  224. // src,
  225. // success: image => {
  226. // console.log(image);
  227. // let allwh = image.height + image.width
  228. // let imgw = (image.width / allwh).toFixed(2)
  229. // let imgh = (image.height / allwh).toFixed(2)
  230. // self.height = imgh * Math.ceil(this.width / imgw)
  231. // self.$nextTick(() => {
  232. // uni.hideLoading()
  233. // this.$refs.canvasRef.changeBgImage(image.path)
  234. // })
  235. // },
  236. // fail(err) {
  237. // wxBase64src.unlink()
  238. // console.log(err);
  239. // }
  240. // })
  241. // },
  242. async changeBgImage(){
  243. let self = this
  244. try {
  245. uni.showLoading({
  246. title: '加载中...'
  247. })
  248. let src = await wxBase64src.base64src(this.imageArr[this.imagesIndex])
  249. const imageInfo = await new Promise((resolve, reject) => {
  250. uni.getImageInfo({
  251. src,
  252. success: resolve,
  253. fail: reject
  254. })
  255. })
  256. let allwh = imageInfo.height + imageInfo.width
  257. let imgw = (imageInfo.width / allwh).toFixed(2)
  258. let imgh = (imageInfo.height / allwh).toFixed(2)
  259. self.height = imgh * Math.ceil(this.width / imgw)
  260. // 确保DOM更新后再更新canvas
  261. await this.$nextTick()
  262. // 先清空画布再设置新图片
  263. // await this.$refs.canvasRef.clearCanvas()
  264. await this.$refs.canvasRef.changeBgImage(imageInfo.path)
  265. // 重新添加签名位置
  266. // this.onAddImage()
  267. } catch(err) {
  268. console.error('changeBgImage error:', err)
  269. wxBase64src.unlink()
  270. } finally {
  271. uni.hideLoading()
  272. }
  273. },
  274. loadFDP(){
  275. let that = this
  276. return new Promise((success, error) => {
  277. uni.chooseMessageFile({
  278. count: 1, //一次可以上传多少个
  279. type: 'file',
  280. extension: ['.pdf'], //文件类型
  281. success(res) {
  282. // that.$Oss.ossUpload(res.tempFiles[0].path)
  283. success(that.$Oss.ossUpload(res.tempFiles[0].path))
  284. },
  285. fail: (err) => {
  286. error(err)
  287. console.log(err, 'err');
  288. }
  289. });
  290. })
  291. },
  292. // 后退
  293. onUndo(event) {
  294. this.$refs.canvasRef.undo();
  295. },
  296. /**
  297. * 导出当前画布为模板
  298. */
  299. onExportJSON() {
  300. this.$refs.canvasRef.exportFun().then(imgArr => {
  301. console.log(imgArr);
  302. uni.previewImage({
  303. urls: [imgArr],
  304. current: 0,
  305. })
  306. }).catch(e => {
  307. console.error(e);
  308. });
  309. },
  310. /**
  311. * 添加文本
  312. */
  313. onAddText() {
  314. this.setData({
  315. graph: {
  316. type: 'text',
  317. text: 'helloworld'
  318. }
  319. });
  320. },
  321. onClearCanvas(event) {
  322. let _this = this;
  323. _this.setData({
  324. canvasBg: null
  325. });
  326. this.$refs.canvasRef.clearCanvas();
  327. },
  328. async submit() {
  329. if(this.$utils.verificationAll(this.form, {
  330. title : '请输入标题',
  331. })){
  332. return
  333. }
  334. let bossPosition = {
  335. // ...this.drawArr.a,
  336. x : this.$utils.rpxSystemInfoInt(this.drawArr.a.x),
  337. y : this.$utils.rpxSystemInfoInt(this.drawArr.a.y),
  338. w : this.$utils.rpxSystemInfoInt(this.drawArr.a.w),
  339. h : this.$utils.rpxSystemInfoInt(this.drawArr.a.h),
  340. }
  341. let employeePosition = {
  342. // ...this.drawArr.b,
  343. x : this.$utils.rpxSystemInfoInt(this.drawArr.b.x),
  344. y : this.$utils.rpxSystemInfoInt(this.drawArr.b.y),
  345. w : this.$utils.rpxSystemInfoInt(this.drawArr.b.w),
  346. h : this.$utils.rpxSystemInfoInt(this.drawArr.b.h),
  347. }
  348. this.form.bossPosition = JSON.stringify(bossPosition)
  349. this.form.employeePosition = JSON.stringify(employeePosition)
  350. this.form.bossPage = this.imagesIndex
  351. this.form.employeePage = this.imagesIndex
  352. this.$api(this.id ? 'updateContractTemplate' :
  353. 'addContractTemplate', this.form).then(res => {
  354. if(res.code == 200){
  355. uni.navigateBack(-1)
  356. }
  357. })
  358. },
  359. // pdf转图片base64
  360. async pdf2imagebase64(){
  361. uni.showLoading({
  362. title: '解析文档中...'
  363. })
  364. let res = await this.$api('pdf2imagebase64', {
  365. pdfPath : this.form.template
  366. })
  367. this.imageArr = []
  368. for(let key in res.result){
  369. this.imageArr.push(res.result[key])
  370. }
  371. },
  372. getDetail(){
  373. if(!this.id){
  374. this.onAddImage()
  375. return
  376. }
  377. this.$api('queryContractTemplateById', {
  378. contractTemplateId : this.id
  379. }).then(async (res) => {
  380. if(res.code == 200){
  381. this.form = res.result
  382. this.imagesIndex = this.form.employeePage
  383. delete this.form.createBy
  384. delete this.form.createTime
  385. delete this.form.updateBy
  386. delete this.form.updateTime
  387. this.onAddImage()
  388. await this.pdf2imagebase64()
  389. this.changeBgImage()
  390. }
  391. })
  392. },
  393. }
  394. }
  395. </script>
  396. <style scoped lang="scss">
  397. .page {
  398. padding-bottom: 100rpx;
  399. .title{
  400. padding: 10rpx 30rpx;
  401. background-color: #fff;
  402. margin-bottom: 10rpx;
  403. input{
  404. padding: 20rpx;
  405. background-color: rgba($uni-color, 0.1);
  406. color: $uni-color;
  407. border: 1rpx solid $uni-color;
  408. border-radius: 10rpx;
  409. }
  410. }
  411. .btn-list {
  412. display: flex;
  413. flex-wrap: wrap;
  414. align-items: center;
  415. padding: 20rpx;
  416. gap: 30rpx;
  417. justify-content: center;
  418. .uni-color-btn {
  419. margin: 0;
  420. border-radius: 10rpx;
  421. }
  422. }
  423. }
  424. </style>