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

1 month ago
3 weeks ago
1 month ago
1 week ago
1 month ago
3 weeks ago
1 month ago
3 weeks ago
1 month ago
1 week ago
1 month ago
2 weeks ago
3 weeks ago
1 month ago
3 weeks ago
1 week ago
3 weeks ago
1 month ago
3 weeks ago
3 weeks ago
3 weeks ago
1 month ago
1 week ago
1 month ago
3 weeks ago
1 month ago
3 weeks ago
3 weeks ago
3 weeks ago
1 week ago
3 weeks ago
1 month ago
3 weeks ago
3 weeks ago
1 month ago
3 weeks ago
1 month ago
3 weeks ago
1 month ago
3 weeks ago
1 week ago
3 weeks ago
3 weeks ago
3 weeks ago
1 month ago
3 weeks ago
1 month ago
3 weeks ago
1 week ago
3 weeks ago
1 week ago
3 weeks ago
1 week ago
3 weeks ago
1 week ago
3 weeks ago
1 week ago
3 weeks ago
1 week ago
3 weeks ago
1 week ago
3 weeks ago
1 week ago
3 weeks ago
1 week ago
3 weeks ago
1 month ago
3 weeks ago
3 weeks ago
3 weeks ago
1 week ago
3 weeks ago
1 week ago
3 weeks ago
1 week ago
3 weeks ago
3 weeks ago
1 week ago
3 weeks ago
1 week ago
3 weeks ago
1 week ago
3 weeks ago
1 month ago
3 weeks ago
1 month ago
1 week ago
1 month ago
1 week ago
3 weeks ago
1 month 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>