ProductSkuPage.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. <template>
  2. <q-page padding>
  3. <!-- <my-upload
  4. field="imageFile"
  5. @crop-success="cropSuccess"
  6. @crop-upload-success="cropUploadSuccess"
  7. @crop-upload-fail="cropUploadFail"
  8. v-model="showImageUpload"
  9. :width="200"
  10. :height="200"
  11. :url="rest_base + '/api/v1/image/upload'"
  12. :params="upload_icon_params"
  13. :headers="headers"
  14. :withCredentials="true"
  15. img-format="jpg"
  16. >
  17. </my-upload> -->
  18. <q-dialog v-model="confirmDelete" persistent>
  19. <q-card>
  20. <q-card-section class="row items-center">
  21. <q-avatar icon="signal_wifi_off" color="primary" text-color="white" />
  22. <span class="q-ml-sm">确定要删除所选吗?</span>
  23. </q-card-section>
  24. <q-card-actions align="right">
  25. <q-btn flat label="取消" color="primary" v-close-popup />
  26. <q-btn
  27. flat
  28. label="确认删除"
  29. color="primary"
  30. @click="executeDelete"
  31. v-close-popup
  32. />
  33. </q-card-actions>
  34. </q-card>
  35. </q-dialog>
  36. <q-dialog v-model="imageUploadBox">
  37. <q-card>
  38. <q-card-section style="width: 300px" class="row items-center q-pb-none">
  39. <div class="text-h6">图片上传</div>
  40. <q-space />
  41. <q-btn icon="close" flat round dense v-close-popup />
  42. </q-card-section>
  43. <q-card-section>
  44. <upload-image
  45. :processImage="customProcessImage"
  46. :removeImage="customRemoveImage"
  47. @update-urls="customHandleUpdatedUrls"
  48. ></upload-image>
  49. </q-card-section>
  50. </q-card>
  51. </q-dialog>
  52. <ProductEditorDialog
  53. ref="updateDetailDialog"
  54. @close-me-event="refreshTable"
  55. />
  56. <!-- <q-dialog
  57. v-model="newskudialog"
  58. :maximized="true"
  59. transition-show="slide-up"
  60. transition-hide="slide-down"
  61. >
  62. <q-card class="bg-cyan-1 text-black">
  63. <q-bar>
  64. <q-space />
  65. <q-btn
  66. dense
  67. flat
  68. icon="minimize"
  69. @click="maximizedToggle = false"
  70. :disable="!maximizedToggle"
  71. >
  72. <q-tooltip v-if="maximizedToggle" class="bg-white text-primary"
  73. >Minimize</q-tooltip
  74. >
  75. </q-btn>
  76. <q-btn
  77. dense
  78. flat
  79. icon="crop_square"
  80. @click="maximizedToggle = true"
  81. :disable="maximizedToggle"
  82. >
  83. <q-tooltip v-if="!maximizedToggle" class="bg-white text-primary"
  84. >Maximize</q-tooltip
  85. >
  86. </q-btn>
  87. <q-btn dense flat icon="close" v-close-popup>
  88. <q-tooltip class="bg-white text-primary">Close</q-tooltip>
  89. </q-btn>
  90. </q-bar>
  91. <q-card-section>
  92. <div class="text-h6">新建产品sku</div>
  93. </q-card-section>
  94. <q-card-section class="q-pt-none">
  95. <div style="width: 100%">
  96. <div class="row justify-center">
  97. <q-select
  98. @update:model-value="(val) => productTypeChange(val)"
  99. outlined
  100. class="col-8"
  101. style="min-width: 200px"
  102. v-model="new_sku_dialog_product_type"
  103. :options="product_type_options"
  104. label="产品类别过滤"
  105. />
  106. </div>
  107. <div class="row justify-center">
  108. <q-input
  109. class="col-8"
  110. filled
  111. v-model="new_sku_dialog_product_name"
  112. label="产品名"
  113. lazy-rules
  114. :rules="[(val) => (val && val.length > 0) || '不能为空']"
  115. />
  116. </div>
  117. <div v-if="insertVideoLinkBox" class="row">
  118. <q-input
  119. class="col-7"
  120. filled
  121. bottom-slots
  122. v-model="videolink"
  123. label="视频链接"
  124. counter
  125. maxlength="120"
  126. :dense="dense"
  127. >
  128. <template v-slot:append>
  129. <q-btn
  130. @click="doInsertVideo"
  131. color="primary"
  132. icon="add_link"
  133. />
  134. </template>
  135. </q-input>
  136. </div>
  137. <div row justify-center>
  138. <q-editor
  139. v-model="new_sku_dialog_description"
  140. ref="newSkuEditor"
  141. :definitions="definitions"
  142. @paste="pasteCapture"
  143. @drop="(evt) => dropCapture(evt)"
  144. :toolbar="[
  145. ['insert_img', 'insert_video'],
  146. [
  147. {
  148. label: $q.lang.editor.align,
  149. icon: $q.iconSet.editor.align,
  150. fixedLabel: true,
  151. options: ['left', 'center', 'right', 'justify'],
  152. },
  153. ],
  154. [
  155. 'bold',
  156. 'italic',
  157. 'strike',
  158. 'underline',
  159. 'subscript',
  160. 'superscript',
  161. ],
  162. ['token', 'hr', 'link', 'custom_btn'],
  163. [
  164. {
  165. label: $q.lang.editor.formatting,
  166. icon: $q.iconSet.editor.formatting,
  167. list: 'no-icons',
  168. options: [
  169. 'p',
  170. 'h1',
  171. 'h2',
  172. 'h3',
  173. 'h4',
  174. 'h5',
  175. 'h6',
  176. 'code',
  177. ],
  178. },
  179. {
  180. label: $q.lang.editor.fontSize,
  181. icon: $q.iconSet.editor.fontSize,
  182. fixedLabel: true,
  183. fixedIcon: true,
  184. list: 'no-icons',
  185. options: [
  186. 'size-1',
  187. 'size-2',
  188. 'size-3',
  189. 'size-4',
  190. 'size-5',
  191. 'size-6',
  192. 'size-7',
  193. ],
  194. },
  195. {
  196. label: $q.lang.editor.defaultFont,
  197. icon: $q.iconSet.editor.font,
  198. fixedIcon: true,
  199. list: 'no-icons',
  200. options: [
  201. 'default_font',
  202. 'arial',
  203. 'arial_black',
  204. 'comic_sans',
  205. 'courier_new',
  206. 'impact',
  207. 'lucida_grande',
  208. 'times_new_roman',
  209. 'verdana',
  210. ],
  211. },
  212. 'removeFormat',
  213. ],
  214. ['quote', 'unordered', 'ordered', 'outdent', 'indent'],
  215. ['undo', 'redo'],
  216. ['viewsource'],
  217. ]"
  218. :fonts="{
  219. arial: 'Arial',
  220. arial_black: 'Arial Black',
  221. comic_sans: 'Comic Sans MS',
  222. courier_new: 'Courier New',
  223. impact: 'Impact',
  224. lucida_grande: 'Lucida Grande',
  225. times_new_roman: 'Times New Roman',
  226. verdana: 'Verdana',
  227. }"
  228. />
  229. </div>
  230. </div>
  231. </q-card-section>
  232. <q-separator inset class="col" />
  233. <div class="row justify-center">
  234. <div class="col-1">自定义属性</div>
  235. </div>
  236. <q-separator inset class="col" />
  237. <q-card-section>
  238. <div v-for="item in rawPropertyBags" v-bind:key="item.attribute_id">
  239. <div class="row justify-left" v-if="item.data_type === 'string'">
  240. <q-input
  241. class="col-8"
  242. outlined
  243. type="textarea"
  244. v-model="
  245. new_sku_dialog_customPropertyBag[
  246. '[string]' + item.attribute_id
  247. ]
  248. "
  249. :label="item.attribute_name + '(最长200字符)'"
  250. :rules="[
  251. (val) =>
  252. val.length <= 200 || 'Please use maximum 200 characters',
  253. ]"
  254. />
  255. </div>
  256. <div class="row justify-left" v-if="item.data_type === 'integer'">
  257. <q-input
  258. class="col-3"
  259. outlined
  260. v-model.number="
  261. new_sku_dialog_customPropertyBag[
  262. '[integer]' + item.attribute_id
  263. ]
  264. "
  265. type="number"
  266. :label="item.attribute_name"
  267. />
  268. </div>
  269. <div v-if="item.data_type === 'date'">
  270. <label>{{ item.attribute_name }}</label>
  271. <br />
  272. <q-date
  273. minimal
  274. v-model="
  275. new_sku_dialog_customPropertyBag['[date]' + item.attribute_id]
  276. "
  277. />
  278. </div>
  279. <div v-if="item.data_type === 'image'">
  280. <q-btn
  281. push
  282. color="primary"
  283. label="上传图标"
  284. @click="toggleImageUpload('[image]' + item.attribute_id)"
  285. />
  286. <q-img
  287. v-if="
  288. new_sku_dialog_customPropertyBag[
  289. '[image]' + item.attribute_id
  290. ] != ''
  291. "
  292. :src="
  293. new_sku_dialog_customPropertyBag[
  294. '[image]' + item.attribute_id
  295. ]
  296. "
  297. spinner-color="white"
  298. style="height: 140px; max-width: 150px"
  299. />
  300. </div>
  301. </div>
  302. </q-card-section>
  303. <q-card-section>
  304. <q-btn color="primary" label="提交" @click="submitWithPropertyBag" />
  305. </q-card-section>
  306. </q-card>
  307. </q-dialog> -->
  308. <div class="row justify-center q-pa-md">
  309. <q-table
  310. ref="productSkuTableRef"
  311. style="max-width: 98%; min-width: 90%"
  312. title="产品细项(具体产品上架)"
  313. :rows="productskus"
  314. :columns="columns"
  315. v-model:pagination="serverPagination"
  316. :loading="loading"
  317. :filter="filter"
  318. row-key="sku_id"
  319. :separator="'cell'"
  320. @request="onRequest"
  321. selection="multiple"
  322. v-model:selected="selected"
  323. >
  324. <template v-slot:top-right>
  325. <q-select
  326. outlined
  327. @update:model-value="(val) => pageProductTypeChange(val)"
  328. style="margin-right: 50px; min-width: 200px"
  329. v-model="product_type_filter"
  330. :options="product_type_options"
  331. label="产品类别过滤"
  332. />
  333. <q-btn
  334. color="deep-orange"
  335. glossy
  336. @click="newProductSKU"
  337. label="新建产品SKU"
  338. style="margin-right: 50px"
  339. />
  340. <q-btn
  341. style="margin-right: 50px"
  342. round
  343. color="primary"
  344. @click="goDelete"
  345. icon="delete"
  346. />
  347. <q-input
  348. borderless
  349. dense
  350. debounce="300"
  351. v-model="filter"
  352. placeholder="Search"
  353. >
  354. <template v-slot:append>
  355. <q-icon name="search" />
  356. </template>
  357. </q-input>
  358. </template>
  359. <template v-slot:body-cell-action="props">
  360. <q-td :props="props">
  361. <q-btn
  362. color="orange"
  363. dense
  364. label="拷贝skuId"
  365. @click="copyText(props.row.sku_id)"
  366. />
  367. <q-btn
  368. color="primary"
  369. dense
  370. label="复制创建"
  371. @click="copyCreate(props.row.sku_id)"
  372. />
  373. <q-btn
  374. color="purple"
  375. dense
  376. label="编辑"
  377. @click="goProductDetail(props.row.sku_id)"
  378. />
  379. </q-td>
  380. </template>
  381. </q-table>
  382. </div>
  383. </q-page>
  384. </template>
  385. <script>
  386. import { api } from "boot/axios";
  387. import { useQuasar } from "quasar";
  388. // import myUpload from "vue-image-crop-upload";
  389. import ProductEditorDialog from "components/ProductEditorDialog.vue";
  390. // import UploadImage from "v-upload-image";
  391. import { myMixin } from "boot/commonFunc";
  392. export default {
  393. name: "ProductSkuPages",
  394. mixins: [myMixin],
  395. components: {
  396. ProductEditorDialog,
  397. // "upload-image": UploadImage,
  398. // "my-upload": myUpload,
  399. },
  400. setup() {
  401. const $q = useQuasar();
  402. return {
  403. showNotifyMessageFail(msg) {
  404. $q.notify({
  405. message: msg,
  406. color: "red",
  407. position: "top-right",
  408. });
  409. },
  410. showNotifyMessageSucceed(msg) {
  411. $q.notify({
  412. message: msg,
  413. color: "green",
  414. position: "top-right",
  415. });
  416. },
  417. showFullPageLoading() {
  418. this.disableAction = true;
  419. $q.loading.show();
  420. },
  421. hideFullPageLoading() {
  422. $q.loading.hide();
  423. this.disableAction = false;
  424. },
  425. };
  426. },
  427. methods: {
  428. copyText(text) {
  429. const unsecuredCopyToClipboard = (text) => {
  430. const textArea = document.createElement("textarea");
  431. textArea.value = text;
  432. document.body.appendChild(textArea);
  433. textArea.focus();
  434. textArea.select();
  435. try {
  436. document.execCommand("copy");
  437. } catch (err) {
  438. console.error("Unable to copy to clipboard", err);
  439. }
  440. document.body.removeChild(textArea);
  441. };
  442. if (window.isSecureContext && navigator.clipboard) {
  443. navigator.clipboard.writeText(text);
  444. this.showNotifyMessageSucceed("成功复制" + text + "到剪贴板");
  445. } else {
  446. unsecuredCopyToClipboard(text);
  447. this.showNotifyMessageSucceed("成功复制" + text + "到剪贴板");
  448. }
  449. },
  450. refreshTable() {
  451. console.log("post create refresh...");
  452. this.$refs.productSkuTableRef.requestServerInteraction();
  453. console.log("ppppppp");
  454. },
  455. cropUploadFail(status, field) {
  456. console.log("-------- upload fail --------");
  457. console.log(status);
  458. console.log("field: " + field);
  459. this.showNotifyMessageFail("上传失败");
  460. },
  461. cropUploadSuccess(jsonData, field) {
  462. console.log("field: " + field);
  463. this.new_sku_dialog_customPropertyBag[this.currentProcessingImageKey] =
  464. jsonData.data;
  465. this.showNotifyMessageSucceed("上传成功");
  466. this.showImageUpload = false;
  467. },
  468. cropSuccess(imgDataUrl, field) {
  469. console.log("-------- crop success --------");
  470. this.imgDataUrl = imgDataUrl;
  471. },
  472. toggleImageUpload(val) {
  473. this.currentProcessingImageKey = val;
  474. this.showImageUpload = !this.showImageUpload;
  475. this.upload_icon_params.expectedType = "thumbnail";
  476. },
  477. changeToEmbeded(originLink) {
  478. if (originLink.indexOf("&") > 0) {
  479. originLink = originLink.substring(0, originLink.indexOf("&"));
  480. }
  481. return originLink.replace("watch?v=", "embed/");
  482. },
  483. doInsertVideo() {
  484. if (this.videolink == null || this.videolink.length < 1) {
  485. this.showNotifyMessageFail("空链接");
  486. return;
  487. }
  488. this.videolink = this.changeToEmbeded(this.videolink);
  489. this.$refs.newSkuEditor.runCmd(
  490. "insertHTML",
  491. `<iframe
  492. src="` +
  493. this.videolink +
  494. `"
  495. width="640"
  496. height="360"
  497. frameborder="0"
  498. allowfullscreen
  499. />`
  500. );
  501. this.insertVideoLinkBox = false;
  502. },
  503. async customProcessImage(image) {
  504. const formData = new FormData();
  505. formData.append("expectedType", "blogImage");
  506. formData.append("imageFile", image);
  507. api
  508. .post("/api/v1/image/upload", formData)
  509. .then((response) => {
  510. console.log("show the response");
  511. console.log(response.data);
  512. this.showNotifyMessageSucceed("成功插入图片");
  513. this.imageUploadBox = false;
  514. this.$refs.newSkuEditor.runCmd("insertImage", response.data.data);
  515. return { imageId: "somefake", imageUrl: response.data.data };
  516. })
  517. .catch((e) => {
  518. this.showNotifyMessageFail(e.toString());
  519. });
  520. },
  521. insertImg() {
  522. this.imageUploadBox = true;
  523. },
  524. insertVid() {
  525. this.insertVideoLinkBox = true;
  526. this.videolink = "";
  527. },
  528. executeDelete() {
  529. console.log("to delete selected:");
  530. console.log(this.selected);
  531. var listOfId2Del = [];
  532. for (var i in this.selected) {
  533. listOfId2Del.push(this.selected[i].sku_id);
  534. }
  535. var params = {};
  536. params.toDelete = listOfId2Del;
  537. api
  538. .delete("/api/v1/productsku/batch", { data: params })
  539. .then((response) => {
  540. this.showNotifyMessageSucceed(response.data.message);
  541. this.$refs.productSkuTableRef.requestServerInteraction();
  542. })
  543. .catch((e) => {
  544. this.showNotifyMessageFail(e.toString());
  545. });
  546. },
  547. goDelete() {
  548. if (this.selected.length < 1) {
  549. this.showNotifyMessageFail("没有选中任何项");
  550. return;
  551. }
  552. this.confirmDelete = true;
  553. },
  554. pageProductTypeChange() {
  555. this.$refs.productSkuTableRef.requestServerInteraction();
  556. },
  557. onRequest(props) {
  558. const { page, rowsPerPage } = props.pagination;
  559. const filter = props.filter;
  560. var storeThis = this;
  561. this.loading = true;
  562. var params = {};
  563. params.page = page;
  564. params.pageSize = rowsPerPage;
  565. params.query = filter;
  566. console.log("what product type filter it is:");
  567. console.log(this.product_type_filter);
  568. params.productTypeId =
  569. this.product_type_filter == "" ? "" : this.product_type_filter.value;
  570. api
  571. .get("/api/v1/productsku", {
  572. params: params,
  573. })
  574. .then((response) => {
  575. console.log(response.data);
  576. this.productskus = response.data.data.data;
  577. console.log("this is the product skus I got:");
  578. console.log(this.productskus);
  579. this.serverPagination.page = response.data.data.currentPage;
  580. this.serverPagination.rowsNumber = response.data.data.total;
  581. this.serverPagination.rowsPerPage = response.data.data.pageSize;
  582. console.log(this.serverPagination);
  583. this.loading = false;
  584. })
  585. .catch((e) => {
  586. console.log(e);
  587. storeThis.showNotifyMessageFail(e.response);
  588. });
  589. },
  590. pasteCapture(evt) {
  591. // Let inputs do their thing, so we don't break pasting of links.
  592. // Let inputs do their thing, so we don't break pasting of links.
  593. if (evt.target.nodeName === "INPUT") return;
  594. let text, onPasteStripFormattingIEPaste;
  595. evt.preventDefault();
  596. evt.stopPropagation();
  597. if (evt.originalEvent && evt.originalEvent.clipboardData.getData) {
  598. text = evt.originalEvent.clipboardData.getData("text/plain");
  599. this.$refs.newSkuEditor.runCmd("insertText", text);
  600. } else if (evt.clipboardData && evt.clipboardData.getData) {
  601. text = evt.clipboardData.getData("text/plain");
  602. this.$refs.newSkuEditor.runCmd("insertText", text);
  603. } else if (window.clipboardData && window.clipboardData.getData) {
  604. if (!onPasteStripFormattingIEPaste) {
  605. onPasteStripFormattingIEPaste = true;
  606. this.$refs.newSkuEditor.runCmd("ms-pasteTextOnly", text);
  607. }
  608. onPasteStripFormattingIEPaste = false;
  609. }
  610. },
  611. dropCapture(evt) {
  612. console.log(evt);
  613. },
  614. loadAllProductTypes() {
  615. var params = {};
  616. // -1 indicates don't want paging at all
  617. params.page = -1;
  618. params.pageSize = -1;
  619. params.query = "";
  620. var storeThis = this;
  621. api
  622. .get("/api/v1/producttype", {
  623. params: params,
  624. })
  625. .then((response) => {
  626. var allProductTypes = response.data.data.data;
  627. this.product_type_options = [];
  628. for (var i in allProductTypes) {
  629. var obj = {};
  630. obj.value = allProductTypes[i].product_type_id;
  631. obj.label = allProductTypes[i].product_type_name;
  632. this.product_type_options.push(obj);
  633. }
  634. })
  635. .catch((e) => {
  636. console.log(e);
  637. storeThis.showNotifyMessageFail(e.response);
  638. });
  639. },
  640. newProductSKU() {
  641. // this.newskudialog = true;
  642. // this.new_sku_dialog_product_name = "";
  643. // this.new_sku_dialog_description = "";
  644. // this.new_sku_dialog_product_type = "";
  645. // this.new_sku_dialog_customPropertyBag = {};
  646. this.$refs.updateDetailDialog.toggleCreateSku();
  647. },
  648. goProductDetail(skuId) {
  649. this.$refs.updateDetailDialog.popMeUp(skuId);
  650. this.editskudialogopen = true;
  651. },
  652. copyCreate(skuId) {
  653. this.$refs.updateDetailDialog.toggleCopyCreateSku(skuId);
  654. },
  655. },
  656. mounted() {
  657. this.getRestBase();
  658. this.$refs.productSkuTableRef.requestServerInteraction();
  659. this.loadAllProductTypes();
  660. },
  661. data() {
  662. return {
  663. currentProcessingImageKey: "",
  664. upload_icon_params: {},
  665. rest_base: "",
  666. image: "",
  667. showImageUpload: false,
  668. icon_image_path: false,
  669. maximizedToggle: false,
  670. videolink: "",
  671. insertVideoLinkBox: false,
  672. imageUploadBox: false,
  673. confirmDelete: false,
  674. editskudialogopen: true,
  675. productskus: [],
  676. rawPropertyBags: [],
  677. new_sku_dialog_customPropertyBag: {},
  678. definitions: {
  679. insert_img: {
  680. tip: "插入图片",
  681. icon: "photo",
  682. handler: this.insertImg,
  683. },
  684. insert_video: {
  685. tip: "插入油管视频",
  686. icon: "play_circle_filled",
  687. handler: this.insertVid,
  688. },
  689. },
  690. new_sku_dialog_description: "",
  691. new_sku_dialog_product_type: "",
  692. new_sku_dialog_product_name: "",
  693. newskudialog: false,
  694. product_type_options: [],
  695. product_type_filter: "",
  696. selected: [],
  697. filter: "",
  698. loading: false,
  699. serverPagination: {
  700. page: 1,
  701. rowsPerPage: 100,
  702. rowsNumber: 10, // specifying this determines pagination is server-side
  703. },
  704. columns: [
  705. {
  706. name: "product_name",
  707. required: true,
  708. label: "产品名",
  709. align: "left",
  710. field: "product_name",
  711. sortable: false,
  712. style:
  713. "max-width: 100px;text-overflow: ellipsis !important;white-space: nowrap !important;overflow: hidden !important;",
  714. },
  715. {
  716. name: "product_type_name",
  717. required: true,
  718. label: "产品类别",
  719. align: "left",
  720. field: "product_type_name",
  721. sortable: false,
  722. style:
  723. "max-width: 100px;text-overflow: ellipsis !important;white-space: nowrap !important;overflow: hidden !important;",
  724. },
  725. {
  726. name: "product_content",
  727. required: false,
  728. label: "产品内容",
  729. align: "left",
  730. field: "product_content",
  731. sortable: false,
  732. style:
  733. "max-width: 100px;text-overflow: ellipsis !important;white-space: nowrap !important;overflow: hidden !important;",
  734. },
  735. {
  736. name: "created_time",
  737. required: true,
  738. label: "创建时间",
  739. align: "left",
  740. field: "created_time",
  741. sortable: false,
  742. style:
  743. "max-width: 120px;min-width: 120px;text-overflow: ellipsis !important;white-space: nowrap !important;overflow: hidden !important;",
  744. },
  745. { name: "action", label: "操作", field: "action" },
  746. ],
  747. };
  748. },
  749. };
  750. </script>