createContract.vue 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950
  1. <template>
  2. <div>
  3. <i-page-header :title="pageTitle"></i-page-header>
  4. <div class="flex">
  5. <div class="left-wrap">
  6. <!-- <el-slider v-model="bl" :min="0.1" :max="1" :step="0.1"></el-slider> -->
  7. <div class="phone">
  8. <div class="content" style="user-select: none;position: relative;" :style="{width: `calc(750px * ${bl})`,
  9. height: `calc(1564px * ${bl})`,
  10. 'border-radius': `calc(120px * ${bl})`,}">
  11. <img v-for="item in menu.images" :src="item" alt="" class="content-img"
  12. :style="{width: `calc(750px * ${bl}`}" />
  13. <template v-for="items in menu.jsonAr">
  14. <div v-drag style="user-select: none;position: absolute;" :style="showStyle(items)"
  15. :id="'j-' + items.code"
  16. v-if="items.type == 'text' || items.type == 'address' || items.type == 'date'|| items.type == 'number'"
  17. @v-drag-end="someFunction">
  18. {{items.val ? items.val: ('甲方-' + items.name)}}
  19. </div>
  20. <div v-drag
  21. style="user-select: none;position: absolute;display: flex;justify-content: center;align-items: center;"
  22. :style="showImgStyle(items)" :id="'j-' + items.code" v-if="items.type == 'img'"
  23. @v-drag-end="someFunction">
  24. 甲方签名
  25. </div>
  26. <div v-drag style="user-select: none;position: absolute;" :style="showImgStyle(items)"
  27. :id="'j-' + items.code" v-if="items.type == 'langtext'" @v-drag-end="someFunction">
  28. 长备注
  29. </div>
  30. </template>
  31. <template v-for="items in menu.jsonBr">
  32. <div v-drag :style="showStyle(items)" :id="'b-' + items.code"
  33. v-if="items.type == 'text' || items.type == 'address' || items.type == 'date'|| items.type == 'number'"
  34. style="user-select: none;position: absolute;" @v-drag-end="someFunctions">
  35. {{items.val ? items.val: ('乙方-' + items.name)}}
  36. </div>
  37. <div v-drag
  38. style="user-select: none;position: absolute;display: flex;justify-content: center;align-items: center;"
  39. :style="showImgStyle(items)" :id="'b-' + items.code" v-if="items.type == 'img'"
  40. @v-drag-end="someFunctions">
  41. 乙方签名
  42. </div>
  43. <div v-drag
  44. style="user-select: none;position: absolute;display: flex;justify-content: center;align-items: flex-start;"
  45. :style="showImgStyle(items)" :id="'b-' + items.code" v-if="items.type == 'langtext'"
  46. @v-drag-end="someFunctions">
  47. 长备注
  48. </div>
  49. </template>
  50. </div>
  51. </div>
  52. </div>
  53. <div class="right-wrap">
  54. <el-form ref="menu" :model="menu" label-width="160px">
  55. <el-form-item label="合同名称:">
  56. <div class="fx-r fx-bc">
  57. <el-input v-model="menu.title" placeholder="请输入合同名称"></el-input>
  58. </div>
  59. </el-form-item>
  60. <el-form-item label="合同底图:">
  61. <div class="fx-r fx-bc">
  62. <div class="fx-r fx-bc fx-ac" v-for="item in menu.images"
  63. style="border: 1px dashed #d9d9d9;width: 82px;height: 82px;margin-right:12px;border-radius: 6px;cursor: pointer;overflow: hidden;">
  64. <img v-lazy="item" :src="item" v-image-preview style="display: block;height: 100%;" />
  65. </div>
  66. <ui-upload :upUrl="upUrl" :fileName="'上传'" :headers="upHeaders" :updata="{isz:0,code:'img'}"
  67. @onUpload="onUpload">
  68. </ui-upload>
  69. </div>
  70. </el-form-item>
  71. <el-form-item label="甲方参数:">
  72. <el-table :data="menu.jsonAr" tooltip-effect="dark" header-cell-class-name="table-header">
  73. <el-table-column prop="name" label="属性名" width="100">
  74. </el-table-column>
  75. <el-table-column prop="code" label="code" width="100">
  76. </el-table-column>
  77. <el-table-column prop="type" label="类型" width="100">
  78. <template slot-scope="scope">
  79. <div>{{ getJsonName(scope.row.type) }}</div>
  80. </template>
  81. </el-table-column>
  82. <el-table-column prop="verify" label="是否必填" width="100">
  83. <template slot-scope="scope">
  84. <div>{{ scope.row.verify == 1 ?'必填': '选填' }}</div>
  85. </template>
  86. </el-table-column>
  87. <el-table-column prop="left" label="x轴坐标" width="100">
  88. <template slot-scope="scope">
  89. <el-input type="number" v-model="scope.row.left"></el-input>
  90. </template>
  91. </el-table-column>
  92. <el-table-column prop="top" label="y轴坐标" width="100">
  93. <template slot-scope="scope">
  94. <el-input type="number" v-model="scope.row.top"></el-input>
  95. </template>
  96. </el-table-column>
  97. <el-table-column prop="val" label="演示值" width="180">
  98. <template slot-scope="scope">
  99. <el-input type="text" v-model="scope.row.val"></el-input>
  100. </template>
  101. </el-table-column>
  102. <el-table-column prop="fontSize" label="字体大小" width="100">
  103. <template slot-scope="scope">
  104. <el-input type="text" v-model="scope.row.fontSize"></el-input>
  105. </template>
  106. </el-table-column>
  107. <el-table-column prop="width" label="长" width="100">
  108. <template slot-scope="scope">
  109. <el-input type="text" v-model="scope.row.width"></el-input>
  110. </template>
  111. </el-table-column>
  112. <el-table-column prop="height" label="宽" width="100">
  113. <template slot-scope="scope">
  114. <el-input type="text" v-model="scope.row.height"></el-input>
  115. </template>
  116. </el-table-column>
  117. <el-table-column label="操作">
  118. <template slot-scope="scope">
  119. <a @click="tapJsonEdit(scope.$index)">编辑</a>
  120. <Divider type="vertical" />
  121. <a @click="tapJsonDel(scope.$index)">删除</a>
  122. </template>
  123. </el-table-column>
  124. </el-table>
  125. <Button style="margin-top: 10px;" @click="tapAddJson" type="primary" size="small">添加自定义</Button>
  126. <Button style="margin-top: 10px;margin-left: 10px;" @click="addBase" type="primary"
  127. size="small">导入基础参数</Button>
  128. </el-form-item>
  129. <el-form-item label="乙方参数:">
  130. <el-table :data="menu.jsonBr" tooltip-effect="dark" header-cell-class-name="table-header">
  131. <el-table-column prop="name" label="属性名" width="100">
  132. </el-table-column>
  133. <el-table-column prop="code" label="code" width="100">
  134. </el-table-column>
  135. <el-table-column prop="type" label="类型" width="100">
  136. <template slot-scope="scope">
  137. <div>{{ getJsonName(scope.row.type) }}</div>
  138. </template>
  139. </el-table-column>
  140. <el-table-column prop="verify" label="是否必填" width="100">
  141. <template slot-scope="scope">
  142. <div>{{ scope.row.verify == 1 ?'必填': '选填' }}</div>
  143. </template>
  144. </el-table-column>
  145. <!-- <el-table-column prop="left" label="x轴坐标" width="100">
  146. <template slot-scope="scope">
  147. <el-input type="number" v-model="scope.row.left"></el-input>
  148. </template>
  149. </el-table-column>
  150. <el-table-column prop="top" label="y轴坐标" width="100">
  151. <template slot-scope="scope">
  152. <el-input type="number" v-model="scope.row.top"></el-input>
  153. </template>
  154. </el-table-column> -->
  155. <el-table-column prop="val" label="演示值" width="180">
  156. <template slot-scope="scope">
  157. <el-input type="text" v-model="scope.row.val"></el-input>
  158. </template>
  159. </el-table-column>
  160. <el-table-column prop="fontSize" label="字体大小" width="100">
  161. <template slot-scope="scope">
  162. <el-input type="text" v-model="scope.row.fontSize"></el-input>
  163. </template>
  164. </el-table-column>
  165. <el-table-column prop="width" label="长" width="100">
  166. <template slot-scope="scope">
  167. <el-input type="text" v-model="scope.row.width"></el-input>
  168. </template>
  169. </el-table-column>
  170. <el-table-column prop="height" label="宽" width="100">
  171. <template slot-scope="scope">
  172. <el-input type="text" v-model="scope.row.height"></el-input>
  173. </template>
  174. </el-table-column>
  175. <el-table-column label="操作">
  176. <template slot-scope="scope">
  177. <a @click="tapJsonEdits(scope.$index)">编辑</a>
  178. <Divider type="vertical" />
  179. <a @click="tapJsonDels(scope.$index)">删除</a>
  180. </template>
  181. </el-table-column>
  182. </el-table>
  183. <Button style="margin-top: 10px;" @click="tapAddJsons" type="primary"
  184. size="small">添加自定义</Button>
  185. <Button style="margin-top: 10px;margin-left: 10px;" @click="addBases" type="primary"
  186. size="small">导入基础参数</Button>
  187. </el-form-item>
  188. <el-form-item label="是否显示:">
  189. <div class="fx-r fx-bc" style="padding-top: 10px;">
  190. <el-radio-group v-model="menu.is_show">
  191. <el-radio :label="1">显示</el-radio>
  192. <el-radio :label="0">隐藏</el-radio>
  193. </el-radio-group>
  194. </div>
  195. </el-form-item>
  196. </el-form>
  197. <el-button type="primary" style="margin-left: 80px;" @click="saveHt">保存</el-button>
  198. </div>
  199. </div>
  200. <Modal v-model="dialogVisible2" title="甲方参数" :modal="false" @on-cancel="editClose2">
  201. <el-form ref="json" :model="json" label-width="120px">
  202. <el-form-item label="属性类型" style="width: 250px;" prop="type"
  203. :rules="[{ required: true, message: '请选择属性类型'}]">
  204. <el-select v-model="json.type" placeholder="属性类型">
  205. <el-option :label="item.name" :value="item.value" :key="item.value"
  206. v-for="item in adverJsonType"></el-option>
  207. </el-select>
  208. </el-form-item>
  209. <!-- verify -->
  210. <el-form-item label="是否必填" style="width: 250px;" prop="type">
  211. <el-select v-model="json.verify" placeholder="是否必填">
  212. <el-option label="选填" :value="0"></el-option>
  213. <el-option label="必填" :value="1"></el-option>
  214. </el-select>
  215. </el-form-item>
  216. <el-form-item label="属性名" prop="name" :rules="[{ required: true, message: '请输入属性名'}]">
  217. <el-input placeholder="请输入属性名" autocomplete="off" v-model="json.name"></el-input>
  218. </el-form-item>
  219. <el-form-item label="code" prop="code" :rules="[{ required: true, message: '请输入属性CODE'}]">
  220. <el-input placeholder="请输入code(为全英文不可输入汉字和其他符号)" autocomplete="off" v-model="json.code"></el-input>
  221. </el-form-item>
  222. <el-form-item label="演示值" prop="val">
  223. <el-input placeholder="请输入演示值" autocomplete="off" v-model="json.val"></el-input>
  224. </el-form-item>
  225. <!-- <el-form-item label="x轴坐标" prop="left" :rules="[{ required: true, message: '请输入x轴坐标'}]">
  226. <el-input placeholder="请输入x轴坐标(0~750)" autocomplete="off" v-model="json.left"></el-input>
  227. </el-form-item>
  228. <el-form-item label="y轴坐标" prop="top" :rules="[{ required: true, message: '请输入x轴坐标'}]">
  229. <el-input placeholder="请输入y轴坐标" autocomplete="off" v-model="json.top"></el-input>
  230. </el-form-item> -->
  231. <el-form-item label="字体大小" prop="fontSize" v-if="json.type == 'text'"
  232. :rules="[{ required: true, message: '请输入字体大小'}]">
  233. <el-input placeholder="请输入字体大小" autocomplete="off" v-model="json.fontSize"></el-input>
  234. </el-form-item>
  235. <el-form-item label="长度" v-if="json.type == 'img' || json.type == 'longtext'" prop="width"
  236. :rules="[{ required: true, message: '请输入长度'}]">
  237. <el-input placeholder="请输入长度" autocomplete="off" v-model="json.width"></el-input>
  238. </el-form-item>
  239. <el-form-item label="高度" v-if="json.type == 'img'|| json.type == 'longtext'" prop="height"
  240. :rules="[{ required: true, message: '请输入高度'}]">
  241. <el-input placeholder="请输入高度" autocomplete="off" v-model="json.height"></el-input>
  242. </el-form-item>
  243. </el-form>
  244. <span slot="footer" class="dialog-footer">
  245. <el-button @click="dialogVisible2 = false">取 消</el-button>
  246. <el-button type="primary" @click="subJson">确 定</el-button>
  247. </span>
  248. </Modal>
  249. <Modal v-model="dialogVisible3" title="乙方参数" :modal="false" @on-cancel="editClose2s">
  250. <el-form ref="jsons" :model="json" label-width="120px">
  251. <el-form-item label="属性类型" style="width: 250px;" prop="type"
  252. :rules="[{ required: true, message: '请选择属性类型'}]">
  253. <el-select v-model="json.type" placeholder="属性类型">
  254. <el-option :label="item.name" :value="item.value" :key="item.value"
  255. v-for="item in adverJsonType"></el-option>
  256. </el-select>
  257. </el-form-item>
  258. <el-form-item label="是否必填" style="width: 250px;" prop="type">
  259. <el-select v-model="json.verify" placeholder="是否必填">
  260. <el-option label="选填" :value="0"></el-option>
  261. <el-option label="必填" :value="1"></el-option>
  262. </el-select>
  263. </el-form-item>
  264. <el-form-item label="属性名" prop="name" :rules="[{ required: true, message: '请输入属性名'}]">
  265. <el-input placeholder="请输入属性名" autocomplete="off" v-model="json.name"></el-input>
  266. </el-form-item>
  267. <el-form-item label="code" prop="code" :rules="[{ required: true, message: '请输入属性CODE'}]">
  268. <el-input placeholder="请输入属性CODE" autocomplete="off" v-model="json.code"></el-input>
  269. </el-form-item>
  270. <el-form-item label="演示值" prop="val">
  271. <el-input placeholder="请输入演示值" autocomplete="off" v-model="json.val"></el-input>
  272. </el-form-item>
  273. <!-- <el-form-item label="x轴坐标" prop="left" :rules="[{ required: true, message: '请输入x轴坐标'}]">
  274. <el-input placeholder="请输入x轴坐标(0~750)" autocomplete="off" v-model="json.left"></el-input>
  275. </el-form-item>
  276. <el-form-item label="y轴坐标" prop="top" :rules="[{ required: true, message: '请输入x轴坐标'}]">
  277. <el-input placeholder="请输入y轴坐标" autocomplete="off" v-model="json.top"></el-input>
  278. </el-form-item> -->
  279. <el-form-item label="字体大小" prop="fontSize" v-if="json.type == 'text'"
  280. :rules="[{ required: true, message: '请输入字体大小'}]">
  281. <el-input placeholder="请输入字体大小" autocomplete="off" v-model="json.fontSize"></el-input>
  282. </el-form-item>
  283. <el-form-item label="长度" v-if="json.type == 'img'|| json.type == 'longtext'" prop="width"
  284. :rules="[{ required: true, message: '请输入长度'}]">
  285. <el-input placeholder="请输入长度" autocomplete="off" v-model="json.width"></el-input>
  286. </el-form-item>
  287. <el-form-item label="高度" v-if="json.type == 'img'|| json.type == 'longtext'" prop="width"
  288. :rules="[{ required: true, message: '请输入高度'}]">
  289. <el-input placeholder="请输入高度" autocomplete="off" v-model="json.height"></el-input>
  290. </el-form-item>
  291. </el-form>
  292. <span slot="footer" class="dialog-footer">
  293. <el-button @click="dialogVisible3 = false">取 消</el-button>
  294. <el-button type="primary" @click="subJsons">确 定</el-button>
  295. </span>
  296. </Modal>
  297. </div>
  298. </template>
  299. <script>
  300. import IPageHeader from "../../../layouts/system/page-header/index";
  301. import UiUpload from "../../../ui/upload/index";
  302. import Setting from "../../../setting";
  303. import util from "../../../libs/util";
  304. import {
  305. createHt,
  306. getDetail
  307. } from '../../../api/system/signing.js'
  308. export default {
  309. components: {
  310. IPageHeader,
  311. UiUpload
  312. },
  313. data() {
  314. return {
  315. menuJsonIndex: 0,
  316. menuJsonIndexs: 0,
  317. bl: 0.5,
  318. json: {},
  319. dialogVisible2: false,
  320. dialogVisible1: false,
  321. dialogVisible3: false,
  322. adverJsonType: [{
  323. "name": "文本类型",
  324. "value": "text"
  325. },
  326. {
  327. "name": "数字类型",
  328. "value": "number"
  329. },
  330. {
  331. "name": "日期类型",
  332. "value": "date"
  333. },
  334. {
  335. "name": "签名",
  336. "value": "img"
  337. },
  338. {
  339. "name": "长备注",
  340. "value": "langtext"
  341. },
  342. {
  343. "name": "地址",
  344. "value": "address"
  345. },
  346. ],
  347. upHeaders: {},
  348. upUrl: "",
  349. pageTitle: '创建合同模板',
  350. menu: {
  351. title: '',
  352. images: [],
  353. jsonAr: [],
  354. jsonBr: [],
  355. is_show: 1
  356. },
  357. checkItem: {},
  358. startX: 0,
  359. startY: 0,
  360. moveX: 0,
  361. moveY: 0,
  362. loading: false,
  363. jsonAr: [{
  364. name: '姓名',
  365. code: 'name',
  366. type: 'text',
  367. left: 200,
  368. top: 20,
  369. fontSize: 20,
  370. val: '',
  371. width: 0,
  372. height: 0,
  373. verify: 1
  374. }, {
  375. name: '联系电话',
  376. code: 'phone',
  377. type: 'text',
  378. left: 200,
  379. top: 60,
  380. fontSize: 20,
  381. val: '',
  382. width: 0,
  383. height: 0,
  384. verify: 1
  385. },
  386. {
  387. name: '身份证号',
  388. code: 'card',
  389. type: 'text',
  390. left: 200,
  391. top: 100,
  392. fontSize: 20,
  393. val: '',
  394. width: 0,
  395. height: 0,
  396. verify: 1
  397. },
  398. {
  399. name: '地址',
  400. code: 'address',
  401. type: 'address',
  402. left: 200,
  403. top: 140,
  404. fontSize: 20,
  405. val: '',
  406. width: 0,
  407. height: 0,
  408. verify: 1
  409. },
  410. {
  411. name: '服务费',
  412. code: 'price',
  413. type: 'text',
  414. left: 200,
  415. top: 180,
  416. fontSize: 20,
  417. val: '',
  418. width: 0,
  419. height: 0,
  420. verify: 1
  421. },
  422. {
  423. name: '定金',
  424. code: 'deposit',
  425. type: 'number',
  426. left: 200,
  427. top: 220,
  428. fontSize: 20,
  429. val: '',
  430. width: 0,
  431. height: 0,
  432. verify: 1
  433. },
  434. {
  435. name: '尾款',
  436. code: 'balance',
  437. type: 'number',
  438. left: 200,
  439. top: 260,
  440. fontSize: 20,
  441. val: '',
  442. width: 0,
  443. height: 0,
  444. verify: 1
  445. },
  446. {
  447. name: '周期',
  448. code: 'period',
  449. type: 'number',
  450. left: 200,
  451. top: 300,
  452. fontSize: 20,
  453. val: '',
  454. width: 0,
  455. height: 0,
  456. verify: 1
  457. },
  458. {
  459. name: '开始时间',
  460. code: 'start_time',
  461. type: 'date',
  462. left: 200,
  463. top: 340,
  464. fontSize: 20,
  465. val: '',
  466. width: 0,
  467. height: 0,
  468. verify: 1
  469. },
  470. {
  471. name: '结束时间',
  472. code: 'end_time',
  473. type: 'date',
  474. left: 200,
  475. top: 380,
  476. fontSize: 20,
  477. val: '',
  478. width: 0,
  479. height: 0,
  480. verify: 1
  481. },
  482. {
  483. name: '签名',
  484. code: 'uid_img',
  485. type: 'img',
  486. left: 200,
  487. top: 420,
  488. fontSize: 20,
  489. val: '',
  490. width: 100,
  491. height: 50,
  492. verify: 1
  493. },
  494. {
  495. name: '签约时间',
  496. code: 'check_time',
  497. type: 'date',
  498. left: 200,
  499. top: 480,
  500. fontSize: 20,
  501. val: '',
  502. width: 100,
  503. height: 50,
  504. verify: 1
  505. },
  506. {
  507. name: '附加条款',
  508. code: 'mark',
  509. type: 'langtext',
  510. left: 200,
  511. top: 580,
  512. fontSize: 20,
  513. val: '',
  514. width: 500,
  515. height: 400,
  516. verify: 0
  517. },
  518. ],
  519. jsonBr: [{
  520. name: '姓名',
  521. code: 'name',
  522. type: 'text',
  523. left: 200,
  524. top: 20,
  525. fontSize: 20,
  526. val: '',
  527. width: 0,
  528. height: 0,
  529. verify: 1
  530. }, {
  531. name: '联系电话',
  532. code: 'phone',
  533. type: 'text',
  534. left: 200,
  535. top: 60,
  536. fontSize: 20,
  537. val: '',
  538. width: 0,
  539. height: 0,
  540. verify: 1
  541. },
  542. {
  543. name: '身份证号',
  544. code: 'card',
  545. type: 'text',
  546. left: 200,
  547. top: 100,
  548. fontSize: 20,
  549. val: '',
  550. width: 0,
  551. height: 0,
  552. verify: 1
  553. },
  554. {
  555. name: '地址',
  556. code: 'address',
  557. type: 'text',
  558. left: 200,
  559. top: 140,
  560. fontSize: 20,
  561. val: '',
  562. width: 0,
  563. height: 0,
  564. verify: 1
  565. },
  566. {
  567. name: '签名',
  568. code: 'to_uid_img',
  569. type: 'img',
  570. left: 200,
  571. top: 420,
  572. fontSize: 20,
  573. val: '',
  574. width: 100,
  575. height: 50,
  576. verify: 1
  577. },
  578. {
  579. name: '签约时间',
  580. code: 'to_check_time',
  581. type: 'date',
  582. left: 200,
  583. top: 420,
  584. fontSize: 20,
  585. val: '',
  586. width: 100,
  587. height: 50,
  588. verify: 1
  589. },
  590. ]
  591. }
  592. },
  593. methods: {
  594. addBase() {
  595. this.menu.jsonAr = this.menu.jsonAr.concat(this.jsonAr)
  596. },
  597. addBases() {
  598. this.menu.jsonBr = this.menu.jsonBr.concat(this.jsonBr)
  599. },
  600. hasDuplicateCode(arr, name) {
  601. const codes = arr.map(item => item[name]);
  602. const uniqueCodes = new Set(codes);
  603. return codes.length !== uniqueCodes.size;
  604. },
  605. saveHt() {
  606. let that = this
  607. if (that.loading) return;
  608. if (!that.menu.title) {
  609. return this.$alert('请输入合同名称');
  610. }
  611. if (that.menu.images.length == 0) {
  612. return this.$alert('请上传合同底图');
  613. }
  614. if (that.jsonAr.length == 0) {
  615. return this.$alert('请添加甲方数据');
  616. }
  617. if (this.hasDuplicateCode(that.jsonAr, 'code')) {
  618. return this.$alert('甲方数据code重复,请修改');
  619. }
  620. if (this.hasDuplicateCode(that.jsonAr, 'name')) {
  621. return this.$alert('甲方数据属性名重复,请修改');
  622. }
  623. if (that.jsonBr.length == 0) {
  624. return this.$alert('请添加乙方数据');
  625. }
  626. if (this.hasDuplicateCode(that.jsonBr, 'code')) {
  627. return this.$alert('乙方数据code重复,请修改');
  628. }
  629. if (this.hasDuplicateCode(that.jsonBr, 'name')) {
  630. return this.$alert('乙方数据属性名重复,请修改');
  631. }
  632. let data = {
  633. title: that.menu.title,
  634. imgs: that.menu.images,
  635. is_show: that.menu.is_show,
  636. content: {
  637. jsonAr: that.menu.jsonAr,
  638. jsonBr: that.menu.jsonBr
  639. },
  640. }
  641. if(that.menu.id) {
  642. data.id = that.menu.id
  643. }
  644. that.loading = true
  645. createHt(data).then(res => {
  646. this.$Message.success("操作成功");
  647. that.loading = false
  648. }).catch(err => {
  649. that.loading = false
  650. localStorage.removeItem('menu')
  651. })
  652. },
  653. someFunction(e) {
  654. console.log(e);
  655. let div = e.target
  656. this.menu.jsonAr = this.menu.jsonAr.map(item => {
  657. // && (div.offsetTop !== 0 && div.offsetLeft !=0)
  658. if (div.id == `j-${item.code}`) {
  659. console.log(div.offsetTop, div.offsetLeft);
  660. item.top = (div.offsetTop / this.bl).toFixed(2)
  661. item.left = (div.offsetLeft / this.bl).toFixed(2)
  662. }
  663. return item
  664. })
  665. localStorage.setItem('menu', JSON.stringify(this.menu));
  666. },
  667. someFunctions(e) {
  668. let div = e.target
  669. this.menu.jsonBr = this.menu.jsonBr.map(item => {
  670. if (div.id == `b-${item.code}`) {
  671. console.log(div.offsetTop, div.offsetLeft);
  672. item.top = (div.offsetTop / this.bl).toFixed(2)
  673. item.left = (div.offsetLeft / this.bl).toFixed(2)
  674. }
  675. return item
  676. })
  677. localStorage.setItem('menu', JSON.stringify(this.menu));
  678. },
  679. textClick(item) {
  680. this.checkItem = item
  681. this.checkItem.isCheck = true
  682. },
  683. textMouseDown(event) {
  684. if (!this.checkItem) return;
  685. var drag = document.getElementById('j-' + this.checkItem.code);
  686. console.log(drag.offsetLeft, drag.offsetTop, 'dddddddddd', 'j-' + this.checkItem.code);
  687. this.checkItem.isDragging = true
  688. // this.startX = e.screenX;
  689. // // this.startY = e.screenY
  690. // this.startX = event.clientX - drag.offsetLeft;
  691. // this.startY = event.clientY - drag.offsetTop;
  692. this.startX = event.clientX;
  693. this.startY = event.clientY;
  694. console.log(this.startX, this.startY);
  695. },
  696. showStyle(item) {
  697. return {
  698. position: 'absolute',
  699. top: `calc(${this.bl} * ${item.top + 'px'})`,
  700. left: `calc(${this.bl} * ${item.left + 'px'})`,
  701. fontSize: `calc(${this.bl} * ${item.fontSize + 'px'})`
  702. }
  703. },
  704. showImgStyle(item) {
  705. return {
  706. position: 'absolute',
  707. border: '1px dashed #000',
  708. top: `calc(${this.bl} * ${item.top + 'px'})`,
  709. left: `calc(${this.bl} * ${item.left + 'px'})`,
  710. fontSize: `calc(${this.bl} * ${item.fontSize + 'px'})`,
  711. width: `calc(${this.bl} * ${item.width + 'px'})`,
  712. height: `calc(${this.bl} * ${item.height + 'px'})`,
  713. }
  714. },
  715. onUpload(res) {
  716. console.log(res);
  717. if (res.code == -1) {
  718. Notice.error({
  719. title: "系统提示",
  720. content: res.msg
  721. });
  722. } else {
  723. this.menu.images.push(res.data.img)
  724. }
  725. },
  726. getJsonName: function(type) {
  727. for (var i in this.adverJsonType) {
  728. if (type == this.adverJsonType[i].value) {
  729. return this.adverJsonType[i].name;
  730. }
  731. }
  732. },
  733. /**
  734. * 删除自定义分类
  735. */
  736. tapJsonDel: function(index) {
  737. this.menu.jsonAr.splice(index, 1);
  738. },
  739. tapJsonDels: function(index) {
  740. this.menu.jsonBr.splice(index, 1);
  741. },
  742. /**
  743. * 修改自定义分类
  744. */
  745. tapJsonEdit: function(index) {
  746. this.menuJsonIndex = index;
  747. this.json = this.menu.jsonAr[index];
  748. this.dialogVisible2 = true;
  749. },
  750. tapJsonEdits: function(index) {
  751. this.menuJsonIndexs = index;
  752. this.json = this.menu.jsonBr[index];
  753. this.dialogVisible3 = true;
  754. },
  755. /**
  756. * 添加自定义分类
  757. */
  758. tapAddJson: function() {
  759. this.dialogVisible2 = true;
  760. this.menuJsonIndex = 'add';
  761. this.json = {
  762. left: 375,
  763. top: 20,
  764. name: '',
  765. code: '',
  766. fontSize: 20,
  767. width: 100,
  768. height: 50
  769. }
  770. },
  771. tapAddJsons: function() {
  772. this.dialogVisible3 = true;
  773. this.menuJsonIndexs = 'add';
  774. this.json = {
  775. left: 375,
  776. top: 20,
  777. name: '',
  778. code: '',
  779. fontSize: 20,
  780. width: 100,
  781. height: 50
  782. }
  783. },
  784. /**
  785. * 关闭弹出层
  786. */
  787. editClose2: function() {
  788. this.dialogVisible2 = false;
  789. },
  790. editClose2s: function() {
  791. this.dialogVisible3 = false;
  792. },
  793. /**
  794. * 自定义分类
  795. */
  796. subJson: function() {
  797. this.$refs['json'].validate((valid) => {
  798. if (valid) {
  799. console.log(this.json, 'this.json', this.menuJsonIndex);
  800. if (this.menuJsonIndex == 'add') {
  801. this.menu.jsonAr.push(JSON.parse(JSON.stringify(this.json)));
  802. } else {
  803. this.menu.jsonAr[this.menuJsonIndex] = JSON.parse(JSON.stringify(this.json));
  804. }
  805. console.log(this.menu.jsonAr);
  806. this.dialogVisible2 = false;
  807. // 缓存合同信息
  808. localStorage.setItem('menu', JSON.stringify(this.menu));
  809. }
  810. });
  811. },
  812. subJsons: function() {
  813. this.$refs['jsons'].validate((valid) => {
  814. if (valid) {
  815. try {
  816. if (this.menuJsonIndexs >= 0) {
  817. this.menu.jsonBr[this.menuJsonIndexs] = JSON.parse(JSON.stringify(this.json));
  818. } else {
  819. this.menu.jsonBr.push(JSON.parse(JSON.stringify(this.json)));
  820. }
  821. } catch (error) {
  822. console.log(error, 'error');
  823. //TODO handle the exception
  824. }
  825. console.log(this.menu.jsonBr, 'this.menu.jsonBr');
  826. this.dialogVisible3 = false;
  827. // 缓存合同信息
  828. localStorage.setItem('menu', JSON.stringify(this.menu));
  829. }
  830. });
  831. },
  832. getDetail() {
  833. getDetail({
  834. id: this.menu.id
  835. }).then(res => {
  836. console.log(res);
  837. let menu = res.data
  838. this.menu.jsonAr = menu.content.jsonAr
  839. this.$set(this.menu,'jsonAr',menu.content.jsonAr)
  840. this.$set(this.menu,'jsonBr',menu.content.jsonBr)
  841. this.$set(this.menu,'images',menu.imgs)
  842. this.$set(this.menu,'title',menu.title)
  843. })
  844. }
  845. },
  846. created() {
  847. var upHeaders = {};
  848. //上传路径
  849. this.upUrl = Setting.apiBaseURL + "/systemv1/upload/index";
  850. //上传header数据
  851. const token = util.cookies.get('system_token');
  852. if (token) {
  853. upHeaders['SYSTEM-ACC-TOKEN'] = token;
  854. }
  855. this.upHeaders = upHeaders;
  856. document.addEventListener('contextmenu', function(event) {
  857. // 阻止默认的上下文菜单
  858. event.preventDefault();
  859. // 自定义的右击事件处理
  860. console.log('自定义右击事件');
  861. // 例如,可以创建一个自定义的菜单
  862. // alert('自定义右击事件触发了!');
  863. console.log(event, 'event');
  864. });
  865. if(this.$route.query && this.$route.query.id) {
  866. console.log('zhe');
  867. this.$set(this.menu,'id',this.$route.query.id)
  868. this.getDetail()
  869. }else {
  870. // let data = JSON.parse(localStorage.getItem('menu'))
  871. // if (data.title || data.images.length > 0) {
  872. // this.menu = data
  873. // }
  874. }
  875. }
  876. }
  877. </script>
  878. <style scoped>
  879. :root {
  880. --bl: 1;
  881. }
  882. .flex {
  883. display: flex;
  884. background-color: #fff;
  885. width: 100%;
  886. padding: 40px;
  887. }
  888. .phone {
  889. background-image: url('/src/assets/img/iphone.png');
  890. background-size: 100% 100%;
  891. padding: 15px 18px;
  892. }
  893. .content {
  894. /* width: 375px;
  895. height: 782px; */
  896. /* height: 1564px; */
  897. background-color: #fff;
  898. overflow-y: auto;
  899. scrollbar-width: none;
  900. /* Firefox */
  901. -ms-overflow-style: none;
  902. /* Internet Explorer 10+ */
  903. position: relative;
  904. }
  905. .content-img {
  906. height: auto;
  907. vertical-align: top;
  908. }
  909. .right-wrap {
  910. width: 100%;
  911. padding: 20px;
  912. }
  913. .content-check {
  914. background-color: lightblue;
  915. border: 1px dashed #000;
  916. cursor: grab;
  917. }
  918. .content-drage {
  919. cursor: grabbing;
  920. }
  921. </style>